我在将SWIG生成的Python包装器包装到C++类时遇到了一个奇怪的问题,其中当将std::map
包装为std::shared_ptr
类型时,我似乎无法使用标准的访问器函数ft
。我设法产生了一个MWE,该MWE重现了我观察到的奇怪行为。
TestMap.h
#include <iostream>
#include <map>
#include <memory>
class fooType{
public:
fooType() { };
~fooType() { };
void printFoo() { std::cerr << "FOO!" << std::endl; }
static std::shared_ptr<fooType> make_shared() {
return std::shared_ptr<fooType>(new fooType());
}
};
class testMap : public std::map<int, std::shared_ptr<fooType> > {
public:
void printBar() { std::cerr << "bar." << std::endl; }
};
然后是我的SWIG接口(interface)文件:
TestMap.i
%module TestMap
%include <std_map.i>
%include <std_shared_ptr.i>
%{
#include "TestMap.h"
%}
%shared_ptr(fooType);
%shared_ptr(testMap);
%shared_ptr(std::map<int, std::shared_ptr<fooType> > );
%template(fooMap) std::map< int, std::shared_ptr<fooType> >;
%include "TestMap.h"
最后,我用来测试界面的测试脚本:
test_interface.py
import TestMap as tm
ft = tm.fooType.make_shared()
myTestMap = tm.testMap()
myTestMap[1] = ft
如所写,尝试使用 map 访问器时出现以下错误:
Traceback (most recent call last):
File "test_interface.py", line 9, in <module>
myTestMap[1] = ft
File "/home/sskutnik/tstSWIG/TestMap.py", line 217, in __setitem__
return _TestMap.fooMap___setitem__(self, *args)
NotImplementedError: Wrong number or type of arguments for overloaded function 'fooMap___setitem__'.
Possible C/C++ prototypes are:
std::map< int,std::shared_ptr< fooType > >::__setitem__(std::map< int,std::shared_ptr< fooType > >::key_type const &)
std::map< int,std::shared_ptr< fooType > >::__setitem__(std::map< int,std::shared_ptr< fooType > >::key_type const &,std::map< int,std::shared_ptr< fooType > >::mapped_type const &
当我检查
myTestMap
和std::shared_ptr
的类型时,它们都是各自类的%shared_ptr(TestMap)
引用:<TestMap.fooType; proxy of <Swig Object of type 'std::shared_ptr< fooType > *' at 0x7fa812e80a80> >
<TestMap.testMap; proxy of <Swig Object of type 'std::shared_ptr< testMap > *' at 0x7fa812e80c90> >
现在,奇怪的是-如果我从我的SWIG接口(interface)文件中省略了
myTestMap
声明并重新编译,则映射访问器(位于 test_interface.py 中)会很愉快。当我检查testMap*
的类型时,它是:<TestMap.testMap; proxy of <Swig Object of type 'testMap *' at 0x7f8eceb50630> >
因此,有两个问题:
shared_ptr
)时,为什么我的访问器调用正常工作,而在我有std::shared_ptr< testMap > *
引用(例如shared_ptr
)时却不能正常工作? testMap*
,如何解决此问题? 奖励问题:,如果我声明存在
std::shared_ptr<testMap>
类型的shared_ptr
类型(即使没有这样初始化),为什么SWIG会自动将testMap
转换为ojit_code类型? 最佳答案
第一次myTestMap = tm.testMap()
创建一个透明的shared_ptr。因此,myTestMap[1]
是对shared_ptr的透明引用,并随后为键分配了值。
第二次myTestMap = tm.testMap()
创建空的std::map,因此myTestMap[1]
是将值分配给 map 的key=1
。%shared_ptr(testMap)
在语义上类似于%template(testMap) shared_ptr<testMap>
。 %template(testMapPtr) shared_ptr<testMap>
将创建一个新的shared_ptr类型testMapPtr
,该类型最初保留NULL(请参阅default constructor),因此testMapPtr[1]
将取消引用NULL值,从而产生一些异常。
更新: %shared_ptr(testMap)
创建一个完全透明的shared_ptr,并使用testMap默认构造函数对其进行初始化。
关于python - SWIG:将std::map访问器与shared_ptr一起使用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45420243/