【发布时间】:2016-03-25 15:03:00
【问题描述】:
我正在尝试使用 SWIG 和 Python 重用一些旧的 c 代码。 现在我很困惑。我得到的错误可以用一个小例子来演示:
bsp.h:
extern void add(int a[], int b[], int c[]);
bsp.c:
#include "bsp.h"
void add(int a[], int b[], int c[])
{
c[0] = a[0] + b[0];
c[1] = a[1] + b[1];
}
bsp.i
%module bsp
%{
#include "bsp.h";
%}
%include "bsp.h";
setup.py:
#!/usr/bin/env python
from distutils.core import setup, Extension
bsp_module = Extension('_bsp',
sources = ['bsp_wrap.c', 'bsp.c']
)
setup(name = 'bsp',
ext_modules = [bsp_module],
py_modules = ["bsp"]
)
示例 Python 文件“pybsp.py”:
import bsp
a = [1, 1]
b = [1, 1]
c = []
bsp.add(a, b, c)
print(c)
我得到了错误:
Traceback (most recent call last):
File "pybsp.py", line 31, in <module>
bsp.add(a, b, c)
TypeError: in method 'add', argument 1 of type 'int []'
现在,我感到困惑的是SWIG Documentation 说: “SWIG 完全支持 C/C++ 指针。此外,SWIG 处理不完整的类型信息也没有问题。”
我也试过添加
%apply int * INPUT { int *a}
%apply int * INPUT { int *b}
%apply int * OUTPUT { int *c}
到我的 .i 文件,这是在这种情况下推荐的,但没有成功。 我的猜测是,我必须在 Python 中创建一个类似对象的指针才能传递,但我不知道它是如何工作的,也希望有一种更简单的方法。
非常感谢您的帮助!
P.S.:你可能猜到了,这是我第一次接触 SWIG,所以很遗憾,我无法从看似相似问题的解决方案中推断出解决方案。
编辑: 我发现对于具有给定维度的数组,如上所述,NumPy 似乎是避免手动包装的好选择。 基本示例给出here. 因此我将函数定义更改为
void add(int* a, int dim_a, int *b, int dim_b, int *c, int dim_c)
现在包装器似乎有机会将 NumPy 数组转换为 C 数组。
i-文件
%module bsp
%{
#define SWIG_FILE_WITH_INIT
#include "bsp.h"
%}
%include "numpy.i"
%init %{
import_array();
%}
%apply (int* IN_ARRAY1, int DIM1){(int* a, int dim_a), (int* b, int dim_b)}
%apply (int* ARGOUT_ARRAY1, int DIM1){(int* c, int dim_c)}
%include "bsp.h"
setup.py
#!/usr/bin/env python
from distutils.core import setup, Extension
import numpy
try:
numpy_include = numpy.get_include()
except AttributeError:
numpy_include = numpy.get_numpy_include()
bsp_module = Extension('_bsp',
sources=['bsp_wrap.c', 'bsp.c'],
include_dirs=[numpy_include]
)
setup(name='bsp',
ext_modules=[bsp_module],
py_modules=["_bsp"]
)
最后是 python 脚本,我想使用 int32 来避免来自 NumPy 的类型转换错误 (int64 -> int32)
import bsp
import numpy as np
a = np.array([1, 1], dtype=np.int32)
b = np.array([1, 1], dtype=np.int32)
c = np.array([1, 1], dtype=np.int32)
bsp.add(a, b, c)
print(c)
现在我摆脱了以前的错误,但我有了一个新的:
File "pybsp.py", line 10, in <module>
bsp.add(a, b, c)
TypeError: Int dimension expected. 'unknown type' given.
有什么建议吗?
【问题讨论】: