You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 03:39:02