Cython生成.so库供C程序调用:符号未找到问题求助
问题根源与解决方案
你的问题核心是两个关键点:@cython.cfunc默认不会导出函数到动态库符号表,且误用了--embed选项导致生成的代码不适合作为C调用的库。
1. 修改Cython代码:确保函数被C可见
@cython.cfunc定义的函数默认是**静态(static)**的,只会在Cython生成的代码内部可见,不会暴露到动态库的符号表中。需要修改函数定义,让它们成为C可调用的导出函数:
方式一:使用@cython.ccall + public属性
import cython @cython.ccall(public=True) def processCsvFile(csv: cython.p_char, selectedColumns: cython.p_char, rowFilterDefinitions: cython.p_char): # 你的函数实现 ... @cython.ccall(public=True) def processCsv(csv_data: cython.p_char, selectedColumns: cython.p_char, rowFilterDefinitions: cython.p_char): # 你的函数实现 ...
方式二:直接用cdef public定义C风格函数
import cython # 根据实际返回值修改void,比如int、char*等 cdef public void processCsvFile(char* csv, char* selectedColumns, char* rowFilterDefinitions): # 你的函数实现 ... cdef public void processCsv(char* csv_data, char* selectedColumns, char* rowFilterDefinitions): # 你的函数实现 ...
2. 调整编译流程:移除--embed选项
--embed是用来生成包含Python解释器入口(main函数)的代码,适合编译成独立可执行文件,完全不适合用来生成供C调用的动态库。正确编译步骤:
步骤1:生成C文件
cython csv_reader_lib/process_csv_file.py -o libcsv.c
步骤2:编译为动态库
gcc -o libcsv.so -shared -fPIC libcsv.c $(python3-config --cflags --ldflags) -lpthread -lm -lutil -ldl -lpython3.12
步骤3:安装并运行
cp libcsv.so /usr/local/lib/ ldconfig # 更新系统动态库缓存 ./test_libcsv
验证导出结果
重新编译后,执行以下命令检查符号是否存在:
nm libcsv.so | grep -i "processcsv"
正常情况下会看到类似输出(T代表符号在文本段,是可被外部调用的导出函数):
000000000000xxxx T processCsvFile 000000000000xxxx T processCsv
额外注意
- C程序调用时,必须在代码中声明函数原型:
void processCsvFile(char* csv, char* selectedColumns, char* rowFilterDefinitions); void processCsv(char* csv_data, char* selectedColumns, char* rowFilterDefinitions); - 编译C程序时要链接你的动态库:
gcc -o test_libcsv test_libcsv.c -lcsv -L/usr/local/lib
内容的提问来源于stack exchange,提问作者jessica arruda
相关产品推荐
相关产品推荐

