在Python中使用SWIG访问C++ typedef

6 投票
1 回答
4964 浏览
提问于 2025-04-17 06:27

我有一个C++的API,想要在Python中使用。我的目标是调用一个名为myfunc的C++函数,这个函数需要一个C++类型的参数,具体定义如下:

/* my_header.h */

namespace my_namespace {
typedef std::vector<Foo> Bar
}

这里的Foo是一个C++类。我已经成功地将这个函数和底层的Foo类进行了封装,但我不知道怎么创建一个Foo类型的向量。我在我的SWIG .i文件中包含了这个头文件,具体如下:

/* my_interface.i */

%{
#include "my_header.h"
typedef my_namespace::Bar Bar;
%}

%include "my_header.h"

我还尝试在SWIG中封装std::vector这个模板,方法如下:

%include std_vector.i
namespace std {
    %template(vector_foo) vector<Foo>;
}

这样做是有效的,我可以在Python中导入vector_foo。但是,当我把vector_foo作为参数传给上面提到的函数时,我遇到了类型错误(TypeError)。而且我也无法用Foo来填充vector_foo。

在Python中,我是这样做的:

>>> a = mymodule.vector_foo()
>>> a
<Swig Object of type 'std::vector <Foo, std::allocator< Foo > > *'
>>> mymodule.myfunc(a, 'string')
TypeError: in method 'myfunc', argument 1 of type 'my_namespace::Bar &'

我希望能让自己的Foo向量实现正常工作,或者以某种方式直接访问C++的类型定义。我是通过SWIG来调用并使用Python的Distutils进行编译的。

谢谢大家的帮助!

1 个回答

2

我解决了这个问题。

看起来问题在于我需要告诉SWIG关于接口文件中%{ %}大括号里已经存在的typedef,也就是:

/* my_interface.i */

%{
#include "my_header.h"
typedef my_namespace::Bar Bar;
%}

typedef my_namespace::Bar Bar;
%include "my_header.h"

虽然我不能百分之百确定这就是错误所在。不过现在我有了像上面那样的接口文件,包装功能正常了。

撰写回答