使用ctypes加载含math.h的C共享库返回值始终为0的问题
问题原因与解决办法
这个问题其实有两个核心原因,咱们逐个拆解:
1. ctypes 默认将函数返回值视为 int 类型
ctypes 对C函数的返回值默认会按int类型处理,但你的mycos函数返回的是double浮点数类型。当cos(30)返回0.154251这个小于1的浮点数时,被强制转换成int就直接截断成0了——这就是你看到返回值为0的直接原因。
解决办法很简单,显式指定函数的返回值和参数类型即可:
from ctypes import * mylib = CDLL('/home/ubuntu/test/libtest.so') # 显式设置返回值为double类型 mylib.mycos.restype = c_double # 同时指定参数类型,避免隐式转换的潜在问题 mylib.mycos.argtypes = [c_double] y = mylib.mycos(30) print(y) # 现在会输出正确的0.15425141199962142
2. 共享库编译时未链接数学库(libm)
你编译共享库的命令是gcc -shared -o libtest.so cos.o,这里缺少了-lm参数。虽然你用C代码测试时,编译命令加了-lm能正常运行,但这是因为编译test.c的时候把libm链接到了最终的可执行文件里,而你的共享库本身并没有正确关联libm,这会导致在某些环境下加载共享库时出现符号未定义的错误(只是你当前环境暂时没触发这个问题)。
正确的共享库编译命令应该是:
gcc -shared -o libtest.so cos.o -lm
这样编译出来的共享库会明确依赖libm.so,不管是C程序还是Python加载时,都能稳定解析cos这个符号。
内容的提问来源于stack exchange,提问作者Farthing
相关产品推荐
相关产品推荐

