为什么Python在返回C字符串时会崩溃?

Fan*_*c23 5 c python ctypes

这是我的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.

aba*_*ert 9

你的问题是你在说谎的类型:

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%的工作而没有任何好处......


NPE*_*NPE 4

您说cdll该函数返回 achar*但实际上它返回 a PyObject*。两者需要达成一致。