在Idris中通过FFI调用第三方C++共享库出现undefined symbol报错
问题原因与修复方案
你遇到的undefined symbol: _ZN17mynamespace6FooC1Ev报错,本质是C++名称修饰后的构造函数符号未被正确关联,该符号对应源码里的mynamespace::Foo::Foo()构造函数,下面是分步修复方案:
1. 修正封装库编译链接顺序
GCC/G++的链接规则为依赖方在前、被依赖库在后,你当前的编译命令把-lfoo_ext放在了源文件wrapper.cpp前面,链接器处理libfoo_ext.so时还未扫描到wrapper.cpp对Foo构造函数的依赖,会直接跳过未引用的符号,导致最终生成的libfoo.so没有关联到对应的构造函数实现。
同时编译共享库需要加-fPIC生成位置无关代码,修正后的编译命令如下:
g++ -shared -fPIC -Iinclude wrapper.cpp -Llib -lfoo_ext -o libfoo.so
2. 解决运行时依赖库找不到问题
编译完成后可以用ldd命令验证libfoo.so的依赖是否正常:
ldd libfoo.so
如果输出中libfoo_ext.so显示not found,说明系统运行时无法定位该库,可以二选一解决:
- 临时方案:运行Idris程序前执行
export LD_LIBRARY_PATH=/替换为你的lib目录绝对路径:$LD_LIBRARY_PATH - 永久方案:编译时添加rpath参数把库路径硬编码到
libfoo.so中,完整命令如下:
g++ -shared -fPIC -Iinclude wrapper.cpp -Llib -lfoo_ext -Wl,-rpath=/替换为你的lib目录绝对路径 -o libfoo.so
3. 修正Idris类型定义
你的C接口cFoo_new返回的是struct cFoo*指针,Idris侧的返回类型需要对应改为指针,避免内存访问错误:
module Foo import System.FFI export Foo : Type Foo = Struct "cFoo" [] %foreign "C:cFoo_new,libfoo" export mkFoo : Ptr Foo
内容的提问来源于stack exchange,提问作者joel
相关产品推荐
相关产品推荐

