如何在Haskell中使用FFI处理结构体?

18

我创建了以下用于读取图像的C语言库:

typedef struct {
    unsigned int height;
    unsigned int width;

    unsigned char* red; //length=height*width
    unsigned char* green;
    unsigned char* blue;
} Contents;

Contents readJPEGFile(const char* inFilename);

我找不到关于如何在Haskell中使用数组和结构体以及Foreign Function Interface的任何信息。我该如何继续才能使用我的库呢?

我尝试使用下面的示例作为基础:http://therning.org/magnus/archives/315,但是hsc文件被编译成了只包含上述C代码而没有其他内容的hs文件(当然它无法编译)。

3个回答

10

基本的FFI支持只包括标量类型。其他所有操作都需要通过地址算术来完成。FFI文档中的关于外部类型的章节提供了基本信息,你也可以在FFI Cookbook中找到一个示例。

曾经可以使用像Green CardH/Direct这样的工具为您生成编组和解组代码。出于我不理解的原因,这些工具已经很长时间没有更新了。据我所知,目前的首选工具是hsc2hs


编辑:如评论中所指出(感谢 ephemient),c2hs也很流行,由于c2hs来自Manuel Chakravarty,它很可能是好的。


2
我过去使用过c2hs(http://www.cse.unsw.edu.au/~chak/haskell/c2hs/),它仍在维护并且在我看来比hsc2hs更容易。 - ephemient
c2hs是一个不错的工具,但无法处理枚举或联合体。 - ChrisQuignon
还有 c2hsc 工具,可以从 C 头文件中自动生成大部分的 hsc 文件。 - John Wiegley

7

听起来你遇到了构建问题;我记得在将FFI接口写入Windows Win32 DDEML库时,我确实使用了你所引用的页面作为例子。例如,我们使用的其中一个结构体是

typedef struct tagHSZPAIR {
    HSZ     hszSvc;
    HSZ     hszTopic;
} HSZPAIR, *PHSZPAIR;

#include "ddeml.h"将其引入到DDEML.hsc文件中。我们使用以下代码进行访问:

data HSZPair = HSZPair HSZ HSZ
instance Storable HSZPair where
    sizeOf _                     = (#size HSZPAIR)
    alignment                    = sizeOf
    peek ptr                     = do svc   <- (#peek HSZPAIR, hszSvc)   ptr
                                      topic <- (#peek HSZPAIR, hszTopic) ptr
                                      return $ HSZPair svc topic
    poke ptr (HSZPair svc topic) = do (#poke HSZPAIR, hszSvc)   ptr svc
                                      (#poke HSZPAIR, hszTopic) ptr topic

不幸的是,我现在无法展示它编译成什么样子,因为我没有一个Windows盒子方便使用,但生成的代码与上面完全一样,只是将#size HSZPAIR替换为(64)或其他内容。

(如果您真的想看看生成了什么,或者需要帮助构建,请给我发电子邮件,我会帮助您。)


-3

1
如果您能提及几个,那就太好了。 - MasterMastic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接