SBCL外部函数接口手册示例在Mac上无法运行的解决咨询
解决Mac上SBCL调用C函数的链接错误
一、调整编译链接命令(核心解决问题)
Mac生成动态库的逻辑和Linux不一样,别用Linux那套ld -shared,直接用clang处理,还能顺便解决符号未定义的问题:
- 先把C代码编译成目标文件:
clang -c -fPIC test.c -o test.o
-c:只编译不链接,生成.o目标文件-fPIC:生成位置无关代码,保证动态库能被正确加载(Mac默认支持,但加上更稳妥)
- 再链接生成Mac兼容的动态库:
clang -dynamiclib test.o -o libtest.dylib -lc
-dynamiclib:Mac专用的动态库生成选项,输出文件后缀是.dylib(不是Linux的.so)-lc:链接C标准库,直接解决_malloc、_printf这些符号找不到的问题- 别直接用
ld命令,clang会自动处理动态库的底层配置,不会出现_main未定义的错误(动态库根本不需要main函数)
二、C代码的必要修改
需要改两处,消除警告还能保证兼容性:
- 必须补上缺失的头文件:
#include <stdio.h>和#include <stdlib.h>,这是标准C的基本要求,不管Linux还是Mac都得加,不然肯定会报函数原型缺失的警告 - 确保函数有明确的定义,比如把原示例的函数补成完整的样子:
#include <stdio.h> #include <stdlib.h> void print_hello() { printf("Hello from C!\n"); }
- 不用改函数的链接属性,C默认的链接方式SBCL就能识别
三、SBCL里的调用步骤
在SBCL里加载生成的.dylib,然后声明调用就行:
;; 加载动态库,换成你自己的文件路径 (load-shared-object "./libtest.dylib") ;; 声明外部函数:第一个字符串是C函数的原名,第二个是Lisp里用的名字 (defforeign-routine ("print_hello" print-hello) :void) ;; 直接调用 (print-hello)
- 如果动态库不在当前目录,要么用绝对路径加载,要么设置
DYLD_LIBRARY_PATH环境变量指定库的位置
内容的提问来源于stack exchange,提问作者kd4ttc
相关产品推荐
相关产品推荐

