如何在Guile Scheme中加载外部C共享库并调用函数?
解决Guile加载本地共享库失败的问题
1. 动态链接器找不到当前目录的库
Linux动态链接器默认不会搜索当前工作目录的共享库,哪怕文件就在当前目录也无法被识别。解决方法:
- 临时生效:启动Guile前先设置环境变量,让链接器包含当前目录:
export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH guile - 长期方案:把库移到系统默认库路径(比如
/usr/local/lib),或者在/etc/ld.so.conf.d/下新建.conf文件写入当前库所在路径,再执行sudo ldconfig刷新缓存。
2. load-extension的初始化函数缺失
你调用(load-extension "libsum" "sum_init")时,Guile会去库中找名为sum_init的初始化函数,但你的sum.c里根本没定义这个函数,这是第二个致命问题。必须修改C代码,添加适配Guile的包装和初始化逻辑:
修改后的sum.c:
#include <libguile.h> // 原sum函数不变 int sum(int a, int b) { return a + b; } // 把C函数包装成Guile能识别的SCM类型函数 SCM scm_sum(SCM a, SCM b) { return scm_from_int(sum(scm_to_int(a), scm_to_int(b))); } // 初始化函数,必须是void类型且无参数,用于向Guile注册sum函数 void sum_init(void) { scm_c_define_gsubr("sum", 2, 0, 0, (scm_t_subr)scm_sum); }
重新编译时要链接Guile的开发库,不然会报头文件或链接错误:
gcc -shared -o libsum.so sum.c `pkg-config --cflags --libs guile-3.0`
现在再启动Guile加载:
(use-modules (system foreign) (system foreign-library)) (load-extension "libsum" "sum_init") (sum 1 2) ; 此时就能正常调用,返回3
替代方案:直接绑定函数无需初始化
如果不想写初始化函数,也可以用load-shared-object直接绑定原C函数:
(use-modules (system foreign)) (define libsum (load-shared-object "./libsum.so")) (define sum (pointer->procedure int (dynamic-func "sum" libsum) (list int int))) (sum 1 2) ; 同样能得到结果3
内容的提问来源于stack exchange,提问作者Display name
相关产品推荐
相关产品推荐

