使用SWIG将Python数组传递给C++函数并返回向量到Python数组

-1 投票
1 回答
595 浏览
提问于 2025-04-18 15:47

我在尝试用SWIG/C++/Python返回一个向量时遇到了困难。

我可以把一个列表传到向量里,增加一些内容,但我想把它(或者其中的一部分)再传回Python,这样就可以在Python中查看这个列表或子列表的结果。

这个例子可以正常工作:

test.i

%module test
%{
#include "test.h"
%}

%include "std_vector.i"

namespace std {
%template(Line)  vector < int >;
    %template(Array) vector < vector < int> >;
}   

void print_array(std::vector< std::vector < int > > myarray);

test.h

#ifndef TEST_H__
#define TEST_H__

#include <stdio.h>
#include <vector>

void print_array(std::vector< std::vector < int > > myarray);

#endif /* TEST_H__ */

test.cpp

#include "test.h"

void print_array(std::vector< std::vector < int > > myarray)
{
    for (int i=0; i<2; i++)
        for (int j=0; j<2; j++)
            printf("[%d][%d] = [%d]\n", i, j, myarray[i][j]);
}

如果你运行下面的Python代码,你会发现它可以正常工作。

>>> import test
>>> a = test.Array()
>>> a = [[0, 1], [2, 3]]
>>> test.print_array(a)
[0][0] = [0]
[0][1] = [1]
[1][0] = [2]
[1][1] = [3]

我在这里尝试修改:

test.i

%module test
%{
#include "test.h"
%}

%include "std_vector.i"

namespace std {
%template(Line)  vector < int >;
    %template(Array) vector < vector < int> >;
}   

std::vector< std::vector < int > print_array(std::vector< std::vector < int > > myarray);

test.h

#ifndef TEST_H__
#define TEST_H__

#include <stdio.h>
#include <vector>

std::vector< std::vector < int > print_array(std::vector< std::vector < int > > myarray);

#endif /* TEST_H__ */

test.cpp

#include "test.h"

std::vector< std::vector < int > print_array(std::vector< std::vector < int > > myarray)
{
    for (int i=0; i<2; i++)
        for (int j=0; j<2; j++)
            printf("[%d][%d] = [%d]\n", i, j, myarray[i][j]);

    std::vector<int>   sub(&myarray[0],&myarray[2]);
    return sub;
}

那么,这样返回一个向量从SWIG是有效的吗?

1 个回答

1

如果你发的代码真的是你在用的,那你缺少一个 ">" 符号。复杂的模板类最好用 typedef 来简化,这样可以让代码更清晰,也能避免这种小错误。比如在你的 .h 文件里,可以试试:

typedef std::vector< std::vector < int > > VecVecInt;
VecVecInt print_array(VecVecInt myarray);

注意,你把向量(vector)作为值传递给函数,这样所有的向量项都会被复制到函数的临时空间里。因为这是一个向量的向量,这样做可能会消耗很多资源。可以考虑使用 const VecVecInt&

撰写回答