SWIG似乎为转换类型为map的struct字段生成了错误的绑定,导致TypeError尝试将map字段设置为python字典。我错过了错误吗?一个不受支持的用例? SWIG中的一个错误?
首先输出
Traceback (most recent call last):
File ".\use_test.py", line 4, in <module>
struct.data = { 'A':1, 'B':2 }
File "C:\Users\kmahan\Projects\SwigTest\test.py", line 150, in <lambda>
__setattr__ = lambda self, name, value: _swig_setattr(self, MyStruct, name, value)
File "C:\Users\kmahan\Projects\SwigTest\test.py", line 49, in _swig_setattr
return _swig_setattr_nondynamic(self,class_type,name,value,0)
File "C:\Users\kmahan\Projects\SwigTest\test.py", line 42, in _swig_setattr_nondynamic
if method: return method(self,value)
TypeError: in method 'MyStruct_data_set', argument 2 of type 'std::map< std::string,unsigned int,std::less< std::string >,std::allocator< std::pair< std::string const,unsigned int > > > *'
这是我的测试用例:
test.i
%module test
%include "std_string.i"
%include "std_map.i"
namespace std {
%template(StringIntMap) map<string, unsigned int>;
}
%{
#include "test.h"
%}
%include "test.h"
test.h
#ifndef _TEST_H_
#define _TEST_H_
#include <string>
#include <map>
struct MyStruct
{
std::map<std::string, unsigned int> data;
};
#endif //_TEST_H_
TEST.CPP
#include "test.h"
run_test.py
import test
struct = test.MyStruct()
struct.data = { 'A':1, 'B':2 }
print struct.data
我使用swig -python -c ++ -o test_wrapper.cpp test.i构建test_wrapper.cpp,编译其他所有内容,并运行run_test.py。
作为一种解决方法,我可以明确定义一个setter(
void setData(const map<string, unsigned int>& data)
)它生成不同的转换代码 - 它通过traits_asptr而不是SWIG_ConvertPtr - 似乎工作但不是非常pythonic!
修改
这是我的.i文件,管道获取和属性本身设置为C ++ getter和setter。我认为这是Nathan在他的回答下面的评论中提出的建议。
%module test
%include "std_string.i"
%include "std_map.i"
namespace std {
%template(StringIntMap) map<string, unsigned int>;
}
struct MyStruct
{
const std::map<std::string, unsigned int>& getData() const;
void setData(const std::map<std::string, unsigned int>&);
%pythoncode %{
__swig_getmethods__["data"] = getData
__swig_setmethods__["data"] = setData
if _newclass:
data = _swig_property(getData, setData)
%}
};
答案 0 :(得分:1)
当您设置struct.data
时,它需要test.StringIntMap
,而不是python dict
。
最简单的方法就是:
struct.data = test.StringIntMap({ 'A':1, 'B':2 })