如果可以列出可能调用的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.