SWIG: Python的list轉為C++的char **型別
阿新 • • 發佈:2018-12-14
Converting Python list to a char **
A common problem in many C programs is the processing of command line arguments, which are usually passed in an array of NULL terminated strings. The following SWIG interface file allows a Python list object to be used as a char ** object.
%module argv // This tells SWIG to treat char ** as a special case %typemap(python,in) char ** { /* Check if is a list */ if (PyList_Check($source)) { int size = PyList_Size($source); int i = 0; $target = (char **) malloc((size+1)*sizeof(char *)); for (i = 0; i < size; i++) { PyObject *o = PyList_GetItem($source,i); if (PyString_Check(o)) $target[i] = PyString_AsString(PyList_GetItem($source,i)); else { PyErr_SetString(PyExc_TypeError,"list must contain strings"); free($target); return NULL; } } $target[i] = 0; } else { PyErr_SetString(PyExc_TypeError,"not a list"); return NULL; } } // This cleans up the char ** array we malloced before the function call %typemap(python,freearg) char ** { free((char *) $source); } // This allows a C function to return a char ** as a Python list %typemap(python,out) char ** { int len,i; len = 0; while ($source[len]) len++; $target = PyList_New(len); for (i = 0; i < len; i++) { PyList_SetItem($target,i,PyString_FromString($source[i])); } } // Now a few test functions %inline %{ int print_args(char **argv) { int i = 0; while (argv[i]) { printf("argv[%d] = %s\n", i,argv[i]); i++; } return i; } // Returns a char ** list char **get_args() { static char *values[] = { "Dave", "Mike", "Susan", "John", "Michelle", 0}; return &values[0]; } %}
When this module is compiled, our wrapped C functions now operate as follows :
>>> from argv import * >>> print_args(["Dave","Mike","Mary","Jane","John"]) argv[0] = Dave argv[1] = Mike argv[2] = Mary argv[3] = Jane argv[4] = John 5 >>> get_args() [`Dave', `Mike', `Susan', `John', `Michelle'] >>>
Our type-mapping makes the Python interface to these functions more natural and easy to use.