Idris FFI"未找到符号"

时间:2015-11-20 02:46:11

标签: ffi idris

我最近一直在和伊德里斯搞混,并决定尝试使用其Network.Socket图书馆。我启动了REPL,导入了模块,并使用socket命令创建了一个套接字。在尝试执行IO操作时,我遇到以下错误:

failed to construct ffun from (Builtins.MkPair (FFI_C.C_Types (Int)) (Int) (FFI_C.C_IntT (Int) (FFI_C.C_IntNative)) (2),Builtins.MkPair (FFI_C.C_Types (Int)) (Int) (FFI_C.C_IntT (Int) (FFI_C.C_IntNative)) (1),[])
Symbol "socket" not found
user error (Could not call foreign function "socket" with args [2,1,0])

为了查看问题是Network.Socket特定的,还是仅仅是FFI,我做了一个虚拟函数。

printf : String -> IO ()
printf = foreign FFI_C "printf" (String -> IO ())

执行:x printf "Hello World"会产生类似的错误:

Symbol "printf" not found
user error (Could not call foreign function "printf" with args ["hello world"])

尽管如此,putStr工作正常。

我正在运行Idris 9.20,通过cabal安装,-f FFI设置为编译。我正在使用通过MacPorts安装的libffi 3.4版。

1 个答案:

答案 0 :(得分:2)

我认为这与Idris FFI的运作方式有关,这取决于代码是在编译还是解释。在编译代码时,FFI要求在C codegen阶段,命名的C函数在范围内,并且在链接C可执行文件时,链接正确的名称。由于Idris的RTS链接到libc,这使得libc中的许多名称都不需要任何额外的工作(某些名称可能需要%include来确保包含正确的C头文件以将它们放在范围内)。在解释代码时,解释器在动态加载的库列表中查找FFI调用,这需要不同的指令:文件中的%dynamic或解释器中的:dynamic。默认情况下,不会加载任何动态库,因此即使libc中的标准名称也不在范围内。这可以通过在文件中包含%dynamic "libc"或在REPL命令行中使用:dynamic "libc"进行一次会话来解决。

相关问题