在运行时从Haskell调用C函数

Ben*_*ris 9 c haskell dynamic ffi

我正在为Haskell中的动态编程语言构建解释器.我想添加一个简单的机制来调用C函数.在过去,我使用Haskell FFI调用我已明确声明其名称和类型的C函数; 这种方法在这里不起作用,因为解释器将不知道要在运行时调用的C函数的名称或类型.

是否可以在运行时声明和调用C函数?我应该从哪里开始?

Hea*_*ink 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 ())
Run Code Online (Sandbox Code Playgroud)

如果你有一个指向C函数的指针,你可以使用这个包装函数从Haskell调用它.

callWithNull :: FunPtr (Ptr a -> IO (Ptr ())) -> IO (Ptr ())
callWithNull f = mkPtrFun f nullPtr
Run Code Online (Sandbox Code Playgroud)

如果编译Haskell代码时C函数的类型未知,则不能使用FFI执行此操作.

动态加载

至于动态获取C函数指针,FFI对您没有帮助.您可以在C中使用动态加载库,例如libdl.请参见手册页:http://linux.die.net/man/3/dlopen.