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

时间:2015-05-21 18:03:23

标签: python c ctypes

这是我的C代码,我用它创建了一个共享库。当我在Python中加载共享库并执行下面的Python代码时,我崩溃了。为什么?

extern "C" { 
PyObject* foo2(char* b) 
{
  return Py_BuildValue("s", b);
}

}

以下是我在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)

如果有帮助,我在Python2.6。

2 个答案:

答案 0 :(得分:9)

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

d.foo2.restype = c_char_p

实际的返回类型是PyObject *。但是ctypes会看到c_char_p,将PyObject *投射到char *,然后尝试将char *转换为{{1}的字符串这将会读取谁知道什么是任意字节,直到它击中NUL字符。

指定PyString_FromString的方式是使用py_object

此外,您可能想要设置PyObject *。而这一次, argtype

c_char_p

但是,正如interjay在评论中指出的那样,构建一个使用Python C API然后通过d = cdll.LoadLibrary('./foo.so') d.foo2.argtypes = [c_char_p] d.foo2.restype = py_object 调用它的C库有点愚蠢。这偶尔有用,但通常情况下,解决方案是完成构建C扩展模块而不是完成80%的工作而没有任何好处......

答案 1 :(得分:4)

您告诉cdll该函数返回char*但实际上它返回PyObject*。这两者需要达成一致。