gpt4 book ai didi

c - haskell C FFI : accessing static data structures

转载 作者:太空狗 更新时间:2023-10-29 16:34:25 24 4
gpt4 key购买 nike

我有一个关于 Haskell C FFI 的问题,特别是关于访问 C 库导出的静态数据结构。

我包装的 C 库具有静态数据结构,如 FOO_GEORGE下面,以下列方式导出:

static struct foo_struct foo_table[] = { /* list of foo structs */ }
typedef struct foo_struct *foo_t;
foo_t FOO_GEORGE = &foo_table[0];
foo_t FOO_HARRY = &foo_table[1];
foo_t FOO_SUSAN = &foo_table[2];
/* ... */

我在 Haskell 库中需要的值是 foo_struct 的地址(&foo_table[n]),即FOO_GEORGE的内容,它以通常的方式放在一个不透明的新类型包装器中(构造函数不从库中导出,只导出类型):

newtype Foo = Foo { getFoo :: (Ptr Foo) }

这就是我现在正在做的:

foreign import ccall "&FOO_GEORGE" fooGeorgeHandle :: Ptr (Ptr Foo)
FooGeorge = Foo . unsafeDupablePerformIO . peek $ fooGeorgeHandle

我认为这是对 unsafePerformIO 的恰当使用, 因为 C API 和实现说 peek 的使用纯净无副作用。此外,我认为我不需要采取 documentation 中要点中列出的任何预防措施。 (以 {-# NOINLINE foo #-} 开头)。

我的总体问题是:我这样做对吗?以上分析是否正确?有没有更好或更好的方法来做到这一点?如果foreign import子句允许我执行指针延迟,这很好,但似乎没有;我错过了什么吗?有人可能会争辩说,这将是一个不好的特性,因为如果指针不好,它可能会出现段错误——但是,peek 也是如此。我必须改用,所以结果是一样的。

谢谢!

最佳答案

John L. 建议使用 CApiFFI 扩展,它完全符合我的要求:允许您导入值而不是位置。现在:

{-# LANGUAGE CApiFFI #-}
newtype {-# CTYPE "foo.h" "struct foo_struct" #-} Foo = Foo { getFoo :: (Ptr Foo) }
foreign import capi "foo.h value FOO_GEORGE" fooGeorgePtr :: Ptr a
fooGeorge = Foo fooGeorgePtr

另一个优点是,无论 FOO_GEORGE 是 C 变量还是预处理器宏,它都有效。我正在使用的 C API 使用这两种 API,并且我链接到的同一 API 的不同实现以不同的方式执行,因此独立于它是很好的。

但是,有一个绊脚石:CApiFFI 不能与 ghci 一起使用!问题是 known , 直到 GHC 8.0.1 才会被修复(当我第一次写这篇文章时,它应该是 7.10,然后被推进)。我有一个非常 hacky 的解决方法。 CApiFFI 的工作原理是动态生成一个 C 库,然后针对它编译和链接 Haskell 程序。完成后删除库; ghci 问题似乎是 .so 文件在 ghci 需要链接到它时已经消失了。我只是在编译期间抓取 .c 文件,然后它被删除,然后自己编译它并告诉 ghci 加载它。由于我不经常更改程序的那部分,因此对我来说效果很好。

我捕获临时 .c 文件的方法是在 Emacs compilation-mode 中启动 ghci,使用 (setq compilation -自动跳转到第一个错误 t)。 Emacs 发现错误并在 GHC 着手删除它之前将 .c 文件加载到缓冲区中 — 当我看到它时,文件已经消失,但我已经在缓冲区中获得了内容。

更新:ghci -fobject-code Foo 有效,但只能看到从模块导出的名称。

关于c - haskell C FFI : accessing static data structures,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25391898/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com