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

为何必须从共享库而非静态链接调用hs_init函数?

问题根源:多RTS实例的隔离

这个问题的核心在于动态共享库和主程序加载了两个完全独立的GHC RTS(运行时系统)实例,它们的运行状态完全隔离,导致初始化状态无法共享。下面拆解两种调用方式的本质差异:

1. 定义_LIB_INIT:调用共享库内的hs_init

当你通过dlsym从libAdd.so获取并调用hs_init时,你初始化的是共享库自身绑定的动态RTS实例:

  • 编译libAdd.so时使用了-dynamic参数,这意味着共享库会链接动态版本的GHC RTS(即libHSrts-ghc8.2.2.so)。
  • hs_add作为共享库导出的函数,它的执行逻辑完全依赖这个共享库绑定的RTS实例,而你调用的hs_init正好完成了该实例的初始化,所以整个流程能正常运行。

2. 移除_LIB_INIT:调用静态链接的hs_init

当你直接调用hs_init时,这个函数属于主程序静态链接的RTS实例:

  • 你的C程序用ghc --make -no-hs-main编译时,默认会静态链接GHC RTS(主程序与该静态RTS绑定为一个整体)。
  • 但动态加载的libAdd.so是独立模块,它自身链接了动态RTS,和主程序的静态RTS是完全分离的两个运行环境。
  • 你初始化了主程序的RTS,但hs_add依赖的共享库RTS实例并未被初始化,因此会抛出RTS is not initialised的错误。

补充:如何让两者共享RTS?

如果想让主程序的hs_init能作用于共享库,需要让两者使用同一个RTS实例,可行方案包括:

  • 编译共享库时移除-dynamic参数,改用静态链接RTS(注意可能存在兼容性限制);
  • 主程序也改为动态链接RTS,且确保共享库与主程序使用同一版本的RTS。

内容的提问来源于stack exchange,提问作者Ed Behn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:50:36