如何在GHCi中测试绑定C对象文件的Haskell FFI外部调用
问题1:异常现象的原因
wrapper_new_person是你在.hsc文件中通过#def自定义的包装函数,hsc2hs会将该函数的实现写入生成的Test_hsc.c文件中,所以这个符号仅存在于Test_hsc.c编译出的Test_hsc.o目标文件里,只要链接阶段没有包含这个目标文件,就会报符号不存在的错误。- 第一次仅加载
Test.o启动GHCi:Test.o依赖wrapper_new_person符号,但没有加载Test_hsc.o,直接触发符号未找到错误。 - 第二次加载
Test.o Test_hsc.o -ltest启动GHCi:所有依赖的目标文件和库都已加载完成,没有启动报错,但GHCi加载纯.o文件时不会自动将对应的Haskell模块导入当前作用域,所以直接查询函数类型会提示变量不在作用域,只要手动执行import Test即可访问模块内的函数。 - 直接加载
Test.hs -ltest -fobject-code启动GHCi:GHCi只会自动处理Test.hs的编译,不会主动识别、编译并链接Test_hsc.c,所以运行时还是找不到Test_hsc.o里的wrapper_new_person符号,偶尔出现的访问违规是符号解析失败后调用非法内存地址导致的。
问题2:无需将Test_hsc.o加入静态库的GHCi测试方法
两种常用可行方案:
方案一:启动GHCi时传入所有相关源文件
直接将Test_hsc.c和Test.hs一起传给GHCi,GHCi会自动编译Test_hsc.c并完成链接:
# 如果libtest.a在当前目录,需要额外加-L.参数指定库搜索路径 ghci Test.hs Test_hsc.c -ltest -fobject-code
进入GHCi交互环境后执行import Test,即可正常调用所有FFI绑定函数。
方案二:提前编译所有目标文件后传入GHCi
先完成所有目标文件的编译:
ghc -c Test.hs Test_hsc.c -ltest
启动GHCi时传入所有目标文件并指定加载Test模块:
ghci -ltest Test.o Test_hsc.o Test
进入交互环境后可直接使用Test模块的导出函数,也可手动执行import Test后调用。
内容的提问来源于stack exchange,提问作者Z-Y.L
相关产品推荐
相关产品推荐

