我在C上有一个简单的测试函数:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>
char fun() {
printf( "%i",12 );
return 'y';
}
编译:
gcc -o test.so -shared -fPIC test.cpp
并在使用ctypes的python中使用它:
from ctypes import cdll
from ctypes import c_char_p
lib = cdll.LoadLibrary('test.so')
hello = lib.fun
hello.restype = c_char_p
print('res',hello())
但后来我收到一个错误:
Traceback (most recent call last): File "./sort_c.py",line 10,in <module>
hello = lib.fun File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py",line 366,in __getattr__
func = self.__getitem__(name) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py",line 371,in __getitem__
func = self._FuncPtr((name_or_ordinal,self))
AttributeError: dlsym(0x100979b40,fun): symbol not found
哪里有问题?
使用:
Mac Os X 10.7.5 and Python 2.7
解决方法
你的第一个问题是C名称错误.如果你在你的.so文件上运行nm,你会得到这样的结果:
nm test.so
0000000000000f40 T __Z3funv
U _printf
U dyld_stub_binder
如果在使用C编译时将其标记为C样式:
#ifdef __cplusplus
extern "C" char fun()
#else
char fun(void)
#endif
{
printf( "%i",12 );
return 'y';
}
nm给出:
0000000000000f40 T _fun
U _printf
U dyld_stub_binder
你的第二个问题是python会因Segmentation故障而死:11(在OS X上). C返回一个char,而你在python中将它标记为指向char的指针.使用:
hello.restype = c_char
相反(改变你的import语句来匹配).
编辑:正如@eryksun所指出的,你不应该使用gcc,你应该使用g代替.否则,将不会链接正确的C运行时.要检查OS X:
otool -L test.so
(ldd,UNIX / Linux上通常使用的工具,不随OS X一起分发)