1

我正在为我编写的科学 C 库创建一个 python 包装器。该库包含一个在编译时全局定义的常量数组,即

const double arr[NARR] = { 200.0, 201.0, ... 899.0, 900.0 };

我想在我的 python 模块中使用 SWIG 使其成为模块级 numpy 数组,即

>>> import foo
>>> foo.arr
array([200.0, 201.0, ..., 889.9, 900.0])

我似乎无法在文档中找到任何内容来使用常量数组执行此操作。一切似乎都处理从函数返回 numpy 数组,或定义非数组常量。

我知道如何通过手动包装数组来做到这一点:

npy_intp dim[1] = { NARR };
PyObject *a = PyArray_SimpleNewFromData(1, dim, NPY_DOUBLE, arr);
PyObject_SetAttrString(module, "arr", a);

我只是无法让它与 SWIG 一起工作。当我尝试将上述代码放入 foo.i 文件的 init 块中时,“arr”变量不会出现在 foo 模块中。

谁能告诉我如何让它正常工作?

编辑

根据 seberg 的建议,更改了手动包装数组的代码示例。

4

1 回答 1

1

我已经找到了解决这个问题的方法,但它非常hackish。

我在我的foo.i文件中包含了两个代码扩展,一个在 C 中,另一个在 python 中。C 扩展创建一个返回 C 数组的函数,以及一个告诉 SWIG 创建一个包装器,该包装器将此 C 数组作为 numpy 数组返回:

/* Tell SWIG I want the function to output a numpy array */
%apply double ARGOUT_ARRAY1[ANY] { double a[NARR] };
/* Create a function that returns a copy of the array */
%inline %{
void _get_arr(double a[NARR]) {
    for (int i = 0; i < NARR; i++)
        a[i] = arr[i];
}
%}

python 扩展调用此函数并将其放入模块级 numpy 数组变量中arr(我将其设为只读以更好地衡量):

%pythoncode %{
# Make the arr array a read-only module-level numpy array
arr = _get_arr()
arr.flags.writeable = False
%}

因为我打算将它作为一个分发,所以我可以控制文件中导入的函数,__init__.py因此_get_arr不会使用foo.

我现在得到了想要的结果:

>>> import foo
>>> foo.arr
array([200.0, 201.0, ..., 889.9, 900.0])
>>> foo.arr[0] = 10
RuntimeError: array is not writeable
>>> foo._get_arr()
AttributeError: 'module' object has no attribute '_get_arr'
于 2013-01-04T03:20:26.117 回答