我有这个功能:
void func(int* a, int b);
我希望在python中提供这样的内容:
func(list, int)
即,用户传递一个列表和一个整数(告诉函数应该在列表中存储多少条目)。为此,我需要在“a”的初始化中知道“b”的值(因为我暂时需要一个原始的C int数组)。
%typemap(in) ( int* a) {
//need to allocate sizeof(int) * b bytes temporarily
}
但我不知道“b”的值,因为它只是稍后解析!
如何访问“b”参数的值?
答案 0 :(得分:1)
您可以使用多参数类型图。
%typemap(in) (const int *a, int b) %{
$2 = (int)PyList_Size($input);
$1 = new int[$2];
for(Py_ssize_t i = 0; i < $2; ++i)
$1[i] = PyLong_AsLong(PyList_GET_ITEM($input,i));
%}
%typemap(freearg) (const int* a, int b) %{
delete [] $1;
%}
这假设您在列表中传递 (因此const int*
)。由于Python列表知道它的大小,因此也不需要传递大小。另请注意,上面的示例中没有错误检查。
这样就可以为这两个参数传递一个Python对象($ input)。 b
($ 2)初始化为大小,a
($ 1)分配该大小的新int
数组。数组的元素将复制到此数组中。
freearg
typemap在调用函数后提供清理。
你这样使用它:
func([1,2,3,4,5])
如果要返回列表,可以使用以下内容:
%typemap(in) (int *a, int b) %{
$2 = (int)PyLong_AsLong($input);
$1 = new int[$2];
%}
%typemap(argout) (int *a, int b) (PyObject* tmp) %{
tmp = PyList_New($2);
for(Py_ssize_t i = 0; i < $2; ++i)
PyList_SET_ITEM(tmp, i, PyLong_FromLong($1[i]));
$result = SWIG_Python_AppendOutput($result, tmp);
%}
%typemap(freearg) (int* a, int b) %{
delete [] $1;
%}
注意非const int *a
。 Python不需要列表作为输入参数来返回一个,因此输入类型映射只需要一个整数(为简洁起见,删除了错误检查)。 argout typemap从返回值构建一个Python列表,并将它们附加到输出结果。
像这样使用:
func(5) # returns for example [1,2,3,4,5]
如果func
有返回值,则会返回[retval, [1,2,3,4,5]]
答案 1 :(得分:0)
我以为我看到你可以使用%apply
复制typemap-for-array-and-length typemap,以便SWIG将它用于你的函数参数。类似的东西(现在无法检查确切的语法):
%apply (int *ARRAY, int LENGTH) { (int* a, int b) };
void func(int* a, int b);
另外,看看Converting Python list to a char **:您可以通过将所有“char *”替换为“int”来使其适应int。