使用 Swig 将 numpy 字符串数组传递给 C
Passing numpy string array to C using Swig
我的 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:
Some data types are not yet supported, like boolean arrays and string arrays.
您要么必须编写一个将字符串作为单独参数的中间函数,将它们放在一个数组中并将其传递给您的 C 函数,要么想出另一种处理方式
所以它是可行的,但是你需要将 numpy 对象数组转换为 python 字符串列表 a.tolist()
。然后您可以使用以下教程代码将其作为 char **
传递给 C 代码
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;
= (char **) malloc((size+1)*sizeof(char *));
for (i = 0; i < size; i++) {
PyObject *o = PyList_GetItem($input,i);
if (PyUnicode_Check(o))
[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();
return NULL;
}
}
[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 *) );
}
基本上只需将 PyString_Check
替换为 PyUnicode_Check
并将 PyString_AsString
替换为 PyUnicode_AsUTF8
(在 python 3.3 及更高版本中引入)
我的 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:
Some data types are not yet supported, like boolean arrays and string arrays.
您要么必须编写一个将字符串作为单独参数的中间函数,将它们放在一个数组中并将其传递给您的 C 函数,要么想出另一种处理方式
所以它是可行的,但是你需要将 numpy 对象数组转换为 python 字符串列表 a.tolist()
。然后您可以使用以下教程代码将其作为 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;
= (char **) malloc((size+1)*sizeof(char *));
for (i = 0; i < size; i++) {
PyObject *o = PyList_GetItem($input,i);
if (PyUnicode_Check(o))
[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();
return NULL;
}
}
[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 *) );
}
基本上只需将 PyString_Check
替换为 PyUnicode_Check
并将 PyString_AsString
替换为 PyUnicode_AsUTF8
(在 python 3.3 及更高版本中引入)