2011-09-14 76 views
4

論點我想寫一個python C包裝的功能(libFunc),其原型是Python的C擴展引用傳遞

libFunc(char**, int*, char*, int) 

如何使用PyArg_ParseTuple爲函數調用設置的參數。這是我目前有的

#include <Python.h> 

    PyObject* libFunc_py(PyObject* self, PyObject* args) 
    { 
     char* input; 
     char** output; 
     int inputlen; 
     int* outputlen; 

     PyArg_ParseTuple(args, "sisi" , output, outputlen, &input, &inputlen); 


     int ret = libFunc(output, outlen, input, inputlen); 


     return Py_BuildValue("i", ret); 
    } 

我能夠使用byref做ctypes。

+1

這是一個使用的例子[用Cython(http://cython.org):libfunc.pyx](https://gist.github.com/cf5e036a88d1b12ea64a) – jfs

+0

感謝代碼..但我沒有在我的環境pyrex。你能告訴我,如何在下面的代碼中釋放內存(由libfunc分配)? – Kamal

+1

1.您的代碼的用戶不需要Cython。您只需要它爲您生成C源代碼。 2.如果'libFunc()'使用'malloc()'爲'output'分配內存,則可以調用'free(輸出)'。 3. s/outlen/outputlen/ – jfs

回答

0

最後我做這種方式

#include <Python.h> 

    PyObject* libFunc_py(PyObject* self, PyObject* args) 
    { 
     char* input; 
     char* output; 
     int inputlen; 
     int outputlen; 

     PyArg_ParseTuple(args, "s#" , &input, &inputlen); 


     int ret = libFunc(&output, &outlen, input, inputlen); 

     if (ret !=0) 
     { 
      Py_ErrSetString(PyExc_RunTimeError, "ErrorMessage"); 
      return NULL; 
     } 

     PyObject* retStr = Py_BuildValue("s#", output,outputlen); 

     if(output) 
      free(output) 

     return retStr; 
    } 
+2

1.'if(!PyArg_ParseTuple(...))return NULL;'2.您可以使用['{PyErr_SetString(PyExc_RuntimeError,「Error message」);返回NULL; }'](http://www.google.com/codesearch#search/&q=PyErr_SetString\%28PyExc_RuntimeError&type=cs),而不是'返回Py_BuildValue(「s#」,「Error」,5)'。 – jfs