在运行时从Haskell调用C函数

9

我正在使用Haskell构建一种动态编程语言的解释器。我想添加一个简单的机制来调用C函数。过去,我使用了Haskell FFI来调用C函数,但那些函数都是我显式声明名称和类型的;这种方法在这里行不通,因为解释器在运行时不会知道要调用的C函数的名称或类型。

有没有可能在运行时声明和调用C函数?我应该从哪里开始?


2
你能否在C语言和Haskell FFI绑定中制作一个动态分派机制呢?换句话说,是否可以有一个单一的Haskell->C调用,根据需要使用C和/或ASM的所有不安全能力进行分支。 - Thomas M. DuBuisson
1个回答

8

动态导入

如果您可以列出可能被调用的C函数的所有可能类型,那么您可以使用FFI的动态导入功能(http://www.haskell.org/onlinereport/haskell2010/haskellch8.html)。 动态导入函数在运行时包装C函数。 您需要为每个可能调用的C函数类型声明一个导入函数。(实际上,只有ABI很重要,因此您可以将所有C指针类型视为等效。)

foreign import ccall "dynamic" mkPtrFun :: FunPtr (Ptr () -> IO (Ptr ())) -> Ptr () -> IO (Ptr ())

如果您有一个指向C函数的指针,您可以使用这个包装函数使其从Haskell中可调用。
callWithNull :: FunPtr (Ptr a -> IO (Ptr ())) -> IO (Ptr ())
callWithNull f = mkPtrFun f nullPtr

如果在Haskell代码编译时不知道C函数的类型,则无法使用FFI实现此操作。

动态加载

对于动态获取C函数指针,FFI并不能帮到您。您可以在C中使用动态加载库(如libdl)。请参阅man页面:http://linux.die.net/man/3/dlopen


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