如何在.chs文件中编码这一块C代码,以便c2hs可以将它转换为相对不错的东西?
typedef enum {
MONOME_BUTTON_UP = 0x00,
MONOME_BUTTON_DOWN = 0x01,
MONOME_ENCODER_DELTA = 0x02,
MONOME_ENCODER_KEY_UP = 0x03,
MONOME_ENCODER_KEY_DOWN = 0x04,
MONOME_TILT = 0x05,
/* update this if you add event types */
MONOME_EVENT_MAX = 0x06
} monome_event_type_t;
typedef struct monome monome_t; /* opaque data type */
typedef struct monome_event monome_event_t;
typedef void (*monome_event_callback_t)
(const monome_event_t *event, void *data);
struct monome_event {
monome_t *monome;
monome_event_type_t event_type;
/* __extension__ for anonymous unions in gcc */
__extension__ union {
struct {
unsigned int x; …
Run Code Online (Sandbox Code Playgroud) hsc2hs和c2hs有什么区别?
我知道hsc2hs是一个预处理器,但它到底是做什么的?
c2hs可以用C代码制作Haskell模块,但是我需要hsc2hs吗?
我正在尝试通过cabal安装gtk,但是,在构建它时我遇到了以下类型错误
[ 22 of 209] Compiling Graphics.UI.Gtk.Embedding.Plug ( dist/build/Graphics/UI/Gtk/Embedding/Plug.hs, dist/build/Graphics/UI/Gtk/Embedding/Plug.o )
Graphics/UI/Gtk/Embedding/Plug.chs:120:6: error:
Couldn't match expected type ‘Ptr ()’
with actual type ‘Maybe DrawWindow’
In the first argument of ‘gtk_plug_new’, namely
‘(fromNativeWindowId (fromMaybe nativeWindowIdNone socketId))’
In the second argument of ‘($)’, namely
‘gtk_plug_new
(fromNativeWindowId (fromMaybe nativeWindowIdNone socketId))’
Graphics/UI/Gtk/Embedding/Plug.chs:137:6: error:
Couldn't match expected type ‘Ptr ()’
with actual type ‘Maybe DrawWindow’
In the second argument of ‘\ (Display arg1) arg2
-> withForeignPtr arg1
$ \ argPtr1 -> gtk_plug_new_for_display argPtr1 arg2’, namely …
Run Code Online (Sandbox Code Playgroud) 我正在使用c2hs编写一些haskell绑定,我想使用Haddock来记录自动生成的构造函数和函数参数.但是,c2hs忽略了评论;
{#enum define WinPos
{
CA as HA -- ^ This comment is not shown in the .hs file
,CB as HB -- ^ Neither this one
}
deriving (Eq,Ord,Show)#}
Run Code Online (Sandbox Code Playgroud)
如何在不编写太多FFI代码的情况下获取这些字段的Haddock文档?
我正在构建一个需要nvcc
编译的软件.我没有支持CUDA的GPU,但实际上我并不需要它 - 朋友正在Linux上构建完全相同的软件,他没有CUDA GPU,但一切都很好.
我从https://developer.nvidia.com/cuda-downloads(cuda_6.5.14_mac_64.pkg
)安装了最新的CUDA工具包,没有任何问题.但是当我构建软件时,我遇到了问题.
我能够以较小的规模重现这个问题:
$ mkdir temp; cd temp; cabal sandbox init
$ cabal get cuda
Unpacking to cuda-0.6.5.0/
$ cd cuda-0.6.5.0/Foreign/CUDA/Analysis
$ c2hs -d trace --cpp=/Developer/NVIDIA/CUDA-6.5/bin/nvcc --cppopts=-ccbin --cppopts=/usr/bin/clang --cppopts=-Xcompiler --cppopts=--stdlib=libstdc++ Device.chs
Attempting to read file `Device.chs'...
...parsing `Device'...
...successfully loaded `Device'.
Invoking cpp as `/Developer/NVIDIA/CUDA-6.5/bin/nvcc -E -x c -ccbin /usr/bin/clang -Xcompiler --stdlib=libstdc++ -U__BLOCKS__ -DC2HS_MIN_VERSION(mj,mn,rv)=(mj<=0&&mn<=18&&rv<=2) Device.chs.h'...
In file included from <built-in>:170:
<command line>:3:29: error: …
Run Code Online (Sandbox Code Playgroud) 我目前正在试验Haskell的C-> Haskell(C2HS)接口生成器.在第一次,这真是太棒了,我extern C
在几个小时内连接了一个相当复杂的C++库(使用一个小型的包装器).(之前我从未做过任何FFI.)
只有一个问题:如何释放在C/C++库中分配的内存?我{#pointer ... foreign #}
在C2HS文档中找到了,它看起来与我追求的完全一样.由于我的C-wrapper将C++库转换为具有参考透明度和功能接口的库,Haskell Storage Manager应该能够为我做好工作:-).不幸的是,我无法让这个工作.为了更好地解释我的问题,我在GitHub上设置了一个小的演示项目,它具有与C/C++库+包装器相同的属性,但没有开销.如您所见,该库与pure unsafe
FFI 一起使用是完全安全的.
在GitHub上,我创建了一个小型演示项目,其组织如下:
C库非常简单和无用:你可以传递一个整数,你可以[0..n]
从库中获取尽可能多的整数(当前).记住:图书馆没用,只是一个演示.界面也很简单:函数LTIData lti_new_data(int n)
将(在传递一个整数之后)返回一些包含C库分配数据的不透明对象.图书馆还拥有两个存取函数int lti_element_count(LTIData data)
和int lti_get_element(LTIData data, int n)
,前者将返回元素的数量,而后者将返回元素n
.嗯,最后但并非最不重要的,该库的用户应该使用它后释放不透明的LTIData
使用void lti_free_data(LTIData data)
.
使用C2HS设置低级Haskell绑定,您可以在其中找到它
为了好玩,我还使用低级API绑定和使用高级API的简单驱动程序设置了一种高级Haskell API.使用驱动程序和例如valgrind,可以很容易地看到泄漏的内存(对于库执行分配的每个参数;可以轻松观察如下):p_1, p_2, ..., p_n
\sum_{i …
AC枚举类型由c2hs呈现到Haskell中,完成Storable
正确编译的实例(TypesC2Hs.chs
).我将这个不合格的导入到我为inline-c
context(Internal.hs
)指定的模块中..hs
由c2hs生成的模块和Internal.hs
导入的模块,InlineC.hs
另一个inline-c
模块包含C调用的quasiquotes.
TypesC2Hs.hs -------------
| |
V V
Internal.hs -------> InlineC.hs
Run Code Online (Sandbox Code Playgroud)
InlineC.hs
抱怨这种类型无法编组:"外国声明中不可接受的参数类型:'DMBoundaryType'无法在外部调用中编组时检查声明:"
到底是怎么回事?这是第一次inline-c
给我这个错误的类型.
我应该注意,其他类型不需要直接解除引用,例如newtype DM = DM (Ptr DM) deriving Storable
,使用上述方法可以正常工作.
提前致谢
TypesC2Hs.chs
{# enum DMBoundaryType as DMBoundaryType {underscoreToCase} deriving (Eq, Show) #}
instance Storable DMBoundaryType where
sizeOf _ = {# sizeof DMBoundaryType #}
alignment _ = {# alignof DMBoundaryType #}
peek = peek
poke = poke
Run Code Online (Sandbox Code Playgroud)
Internal.hs …
我构建并运行以下最小示例(无外部依赖项)
C->Haskell Compiler, version 0.25.2 Snowboundest, 31 Oct 2014
build platform is "x86_64-darwin" <1, True, True, 1>
; 构建命令:
c2hs Structs.chs
ghci Structs.hs
Run Code Online (Sandbox Code Playgroud)
但链接器抱怨了
During interactive linking, GHCi couldn't find the following symbol: get_foo
Run Code Online (Sandbox Code Playgroud)
问:为什么会这样,我该如何解决?Thx提前
答:tl; dr:我没有将.c编译成.o目标代码,DUH!
代码如下:
Structs.chs
module Main where
import Foreign
import Foreign.C
#include "Structs.h"
{#pointer *foo as Foo#}
{#fun get_foo {`Int'} -> `Foo' return* #}
main :: IO ()
main = do
foo <- get_foo 3
a1 <- {#get struct foo->a#} foo
print a1
Run Code Online (Sandbox Code Playgroud)
Structs.h
struct …
Run Code Online (Sandbox Code Playgroud) 我想在C函数中包装一个类似函数的C宏(然后用一个{#fun ... #}
块将它包装在Haskell中),但是c2hs
预处理器会在do.. while(0)
语法上扼杀; 这是代码:
module TestMacro where
#c
#define TestF1(n) do{if n==0 return 0;else return 1; } while(0)
int c_testF1(int x)
{ return ( TestF1(x) ); }
#endc
Run Code Online (Sandbox Code Playgroud)
这是错误:
c2hs TestMacro.chs
c2hs: C header contains errors:
TestMacro.chs.h:6: (column 12) [ERROR] >>> Syntax error !
The symbol `do' does not fit here.
make: *** [main] Error 1
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我的目标是包装CHKERRQ
PETSc库的宏,定义如下petscerror.h
(为了便于阅读,分成多行):
#define CHKERRQ(n)
do {if (PetscUnlikely(n))
return PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,n,PETSC_ERROR_REPEAT," ");}
while (0)
Run Code Online (Sandbox Code Playgroud)