【发布时间】:2015-10-23 16:10:44
【问题描述】:
我的 C 程序需要一个 char** 输入,我将它作为字符串的 numpy 对象数组存储在 python 中。
a = np.empty(2, dtype=object)
a[0] = 'hi you'
a[1] = 'goodbye'
考虑到numpy.i 只为char* 数组定义类型映射,将它传递给我的C 程序的正确方法是什么?
【问题讨论】:
我的 C 程序需要一个 char** 输入,我将它作为字符串的 numpy 对象数组存储在 python 中。
a = np.empty(2, dtype=object)
a[0] = 'hi you'
a[1] = 'goodbye'
考虑到numpy.i 只为char* 数组定义类型映射,将它传递给我的C 程序的正确方法是什么?
【问题讨论】:
那是 impossibru AFAIK,as far as the docs go:
尚不支持某些数据类型,例如布尔数组和字符串数组。
您要么必须编写一个将字符串作为单独参数的中间函数,将它们放入一个数组中并将其传递给您的 C 函数,要么制定另一种处理方式
【讨论】:
所以它是可行的,但你需要将numpy对象数组转换为带有a.tolist()的python字符串列表。然后您可以将其传递给 C 代码,使用以下教程代码作为 char **
http://www.swig.org/Doc1.3/Python.html#Python_nn59
编辑:事实证明这对 *** 来说是一个真正的痛苦,因为上面的示例适用于 Python 2,但在 Python 3 中给出了无用的错误消息。Python 3 移至 unicode 字符串,我不得不阅读一些文档来制作这行得通。这是上面示例的 python 3 等价物。
// This tells SWIG to treat char ** as a special case
%typemap(in) char ** {
/* Check if is a list */
if (PyList_Check($input)) {
int size = PyList_Size($input);
Py_ssize_t i = 0;
$1 = (char **) malloc((size+1)*sizeof(char *));
for (i = 0; i < size; i++) {
PyObject *o = PyList_GetItem($input,i);
if (PyUnicode_Check(o))
$1[i] = PyUnicode_AsUTF8(PyList_GetItem($input,i));
else {
//PyErr_SetString(PyExc_TypeError,"list must contain strings");
PyErr_Format(PyExc_TypeError, "list must contain strings. %d/%d element was not string.", i, size);
free($1);
return NULL;
}
}
$1[i] = 0;
} else {
PyErr_SetString(PyExc_TypeError,"not a list");
return NULL;
}
}
// This cleans up the char ** array we malloc'd before the function call
%typemap(freearg) char ** {
free((char *) $1);
}
基本上只需将PyString_Check 替换为PyUnicode_Check 并将PyString_AsString 替换为PyUnicode_AsUTF8(在python 3.3 及更高版本中引入)
【讨论】: