SWIG将C++封装为Python:将字符串列表转换为STL字符串的STL向量
我想用SWIG把一个C++函数包装起来,这个函数接受一个STL字符串的向量作为输入参数:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void print_function(vector<string> strs) {
for (unsigned int i=0; i < strs.size(); i++)
cout << strs[i] << endl;
}
我想把它包装成一个可以在名为`mymod`的模块中使用的Python函数:
/*mymod.i*/
%module mymod
%include "typemaps.i"
%include "std_string.i"
%include "std_vector.i"
%{
#include "mymod.hpp"
%}
%include "mymod.hpp"
当我用下面的命令构建这个扩展时:
from distutils.core import setup, Extension
setup(name='mymod',
version='0.1.0',
description='test module',
author='Craig',
author_email='balh.org',
packages=['mymod'],
ext_modules=[Extension('mymod._mymod',
['mymod/mymod.i'],
language='c++',
swig_opts=['-c++']),
],
)
然后我导入它并尝试运行时,出现了这个错误:
Python 2.7.2 (default, Sep 19 2011, 11:18:13)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mymod
>>> mymod.print_function("hello is seymour butts available".split())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: in method 'print_function', argument 1 of type 'std::vector< std::string,std::allocator< std::string > >'
>>>
我猜这意味着SWIG没有提供一个默认的类型映射,用来将Python字符串的列表转换为C++ STL字符串的向量。我觉得这可能是SWIG默认提供的某个地方的功能,但我可能不知道该包含哪个文件。那么我该怎么做才能让它正常工作呢?
提前谢谢你!
2 个回答
2
SWIG确实支持将一个列表传递给一个接受向量作为值的函数,或者接受常量向量引用的函数。你可以在这个链接中看到相关的例子:http://www.swig.org/Doc2.0/Library.html#Library_std_vector。我觉得你发的内容没有什么问题。可能是其他地方出了问题,比如Python找到的DLL不是最新的,或者在头文件中使用了“using namespace std”,这会让SWIG的包装代码在进行类型检查时感到困惑(一般来说,在.hpp文件中使用“using namespace”是不推荐的,因为它会把std中的所有内容都引入到全局命名空间中),等等。
19
你需要告诉SWIG你想要一个字符串的向量类型映射。它不会自动猜测所有可能存在的向量类型。
这个信息可以在Schollii提供的链接中找到:
//To wrap with SWIG, you might write the following:
%module example
%{
#include "example.h"
%}
%include "std_vector.i"
%include "std_string.i"
// Instantiate templates used by example
namespace std {
%template(IntVector) vector<int>;
%template(DoubleVector) vector<double>;
%template(StringVector) vector<string>;
%template(ConstCharVector) vector<const char*>;
}
// Include the header file with above prototypes
%include "example.h"