这是我的C代码,我用它创建了一个共享库.当我在Python中加载共享库并执行下面的Python代码时,我崩溃了.为什么?
extern "C" {
PyObject* foo2(char* b)
{
return Py_BuildValue("s", b);
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我在Python中所做的事情:
from ctypes import *
d = cdll.LoadLibrary('./foo.so')
d.foo2.restype = c_char_p
v = d.foo2('hello world')
print pythonapi.PyString_Size(v)
Run Code Online (Sandbox Code Playgroud)
如果它有帮助,我在Python2.6.
你的问题是你在说谎的类型:
d.foo2.restype = c_char_p
Run Code Online (Sandbox Code Playgroud)
实际的返回类型是PyObject *.但是ctypes要看到c_char_p,将其转换PyObject *为a char *,然后尝试将其转换char *为一个字符串PyString_FromString,这将读取谁知道什么是任意字节,直到它击中NUL字符.
指定a的方法PyObject *是py_object.
此外,您可能想要设置argtypes.而这个时候,它真的是一个c_char_p:
d = cdll.LoadLibrary('./foo.so')
d.foo2.argtypes = [c_char_p]
d.foo2.restype = py_object
Run Code Online (Sandbox Code Playgroud)
但是,正如interjay在评论中指出的那样,构建一个使用Python C API然后通过它调用它的C库有点愚蠢ctypes.这有时是有用的,但通常情况下,解决方案是完成构建C扩展模块而不是完成80%的工作而没有任何好处......