使用 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 及更高版本中引入)