SWIG Python to C++: TypeError trying to set struct member of type map -
SWIG Python to C++: TypeError trying to set struct member of type map<string, int> -
swig seems generating wrong bindings converting struct field of type map, resulting in typeerror trying set map field python dictionary. there error missing? unsupported use-case? bug in swig?
first output
traceback (most recent phone 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 homecoming _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: homecoming 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 > > > *'
and here test case:
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
i build test_wrapper.cpp swig -python -c++ -o test_wrapper.cpp test.i, compile else, , run run_test.py.
as workaround can explicitly define setter instead ( void setdata(const map<string, unsigned int>& data)
) generates different conversion code -- goes through traits_asptr instead of swig_convertptr -- , seems work not pythonic!
edit
here .i file pipes gets , sets of attribute c++ getters , setters. think nathan suggested in comment below answer.
%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: info = _swig_property(getdata, setdata) %} };
when you're setting struct.data
, it's expecting test.stringintmap
, not python dict
.
the easiest thing this:
struct.data = test.stringintmap({ 'a':1, 'b':2 })
c++ python dictionary map swig
Comments
Post a Comment