2012-11-05 37 views
3

在我的Python程序的C扩展中,我试图通过将主C函数(称为数百万次)的两个输入设置为全局变量来提高性能,因为它们不会经常更改,所以我不必一直使用lambda封装将它们从Python函数提供给C函数(这浪费了大量的时间)。我的代码看起来像这样。C-Python扩展中的全局PyObject *变量

unsigned char* splitArray; 
PyObject* wordCmp; 

然后Python的API函数来设置它们::第一I在该文件的顶部声明全局变量

static PyObject* py_set_globals(PyObject *self, PyObject *args) 
{ 
    free(wordCmp); 
    free(splitArray); 

    char* splitChars; 
    PyObject* wordC; 

    if (!PyArg_ParseTuple(args, "sO", &splitChars, &wordC)) 
     return NULL; 

    wordCmp = (PyObject*)malloc(sizeof(PyObject)); 
    memcpy(wordCmp, wordC, sizeof(PyObject)); 
    splitArray = splitchars_to_mapping(splitChars); 

    return Py_BuildValue(""); 
} 

在这种情况下,splitArray被分配给128个字符阵列,其在函数splitchars_to_mapping中是malloc的,而wordCmp是一个传递给C的Python函数对象。无论如何,就我所知,char * splitArray可以很好地作为全局变量,但是当我稍后尝试调用wordCmp使用PyEval_CallObject,Python/C崩溃。所以我有两个问题:

  1. 为什么C不会立即崩溃当我尝试释放未初始化的指针wordCmp和splitArray在函数的开始?
  2. 为什么我以后在我将它正确地存储在堆上并将其引用为全局引用时无法调用wordCmp?

回答

3

关于第一个问题,为什么free'ing未初始化的全局变量时,它不会崩溃,这是因为全球(静态)变量初始化为zero程序加载时(guaranteed by the standard),当你调用free()NULL(或零)它什么都不做。

从人free(1)

免费(PTR)已经被调用之前,会出现未定义的行为。 如果ptr为NULL,则不执行任何操作。

编辑: 你的第二个问题是有关事实,你正在试图复制PyObject,你不应该这样做,因为PyObject结构可能包含指针,你不能做复制,因为您没有访问该结构,则应该增加但引用计数,并保持周围参考以备后用,注意,当您使用O引用计数递增,从docs

O(object)[PyObject *] 将一个Python对象(不经任何转换)存储在一个C对象指针中。 C程序因此收到通过的实际对象 。 对象的引用计数没有增加。

所以,你应该自己增加引用,看到这example

static PyObject *my_callback = NULL; 

static PyObject* my_set_callback(PyObject *dummy, PyObject *args) 
{ 
    PyObject *result = NULL;  
    if (PyArg_ParseTuple(args, "O:set_callback", &my_callback)) { 
     if (!PyCallable_Check(my_callback)) { 
      PyErr_SetString(PyExc_TypeError, "parameter must be callable"); 
      return NULL; 
     } 
     Py_XINCREF(my_callback); /* Add a reference to new callback */   
     Py_INCREF(Py_None);  /* Boilerplate to return "None" */ 
     result = Py_None; 
    } 
    return result; 
} 
+0

好吧,谢谢。所以我的声明等价于“unsigned char * splitArray = NULL; PyObject * wordCmp = NULL;”? – dpitch40

+0

@ dpitch40是的,这是由标准保证,看到这个答案http://stackoverflow.com/a/6212973/1157444 – iabdalkader

+0

@ dpitch40检查更新的答案 – iabdalkader