我遇到了一个SWIG生成的Python封装到C++类的奇怪问题,其中我似乎无法使用标准存取函数std::map
,当它被封装为std::shared_ptr
类型时。我设法产生了一个能够再现我所观察到的奇怪行为的MWE。SWIG:使用std :: map访问器与shared_ptr?
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; }
};
然后我痛饮接口文件:
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
至于写,我得到以下错误,当我尝试使用地图访问:
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 &
当我检查的ft
和myTestMap
型两种,分别为std::shared_ptr
参考号:
<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> >
现在的奇数部分 - 如果我省略了SWIFT接口文件中的%shared_ptr(TestMap)
声明并重新编译,映射存取器(位于test_interface.py)很高兴地工作。当我检查的myTestMap
类型,它是:
<TestMap.testMap; proxy of <Swig Object of type 'testMap *' at 0x7f8eceb50630> >
于是,两个问题:
- 为什么我访问函数调用正常工作时,我有一个痛饮对象的指针引用(
testMap*
),而不是在我有一个shared_ptr
参考(例如,std::shared_ptr<testMap> *
)? - 我如何解决这个问题,因为我需要一个
shared_ptr
为我的派生地图类型?
奖金的问题:为什么SWIG自动转换testMap*
为std::shared_ptr<testMap>
类型,如果我宣布一个shared_ptr
类型的testMap
类型的存在
至于“Bonus question”:'%shared_ptr(testMap)'与%template(testMap)shared_ptr'相同。使用'%template(testMapPtr)shared_ptr '来避免testMap语义的这种变化。 –
luart
这个解释对我来说很有意义。我注意到的是,即使我创建了一个方法来为testMap显式创建一个非空的shared_ptr,我也遇到了同样的问题。然而,我注意到当我从共享指针模板(例如'%template(testMapPtr)std :: shared_ptr'中分离出testMap的定义时,我反而得到了项目赋值操作符(有用)的错误不支持 将智能指针模板从基类中分离出来,然后在需要智能指针类型时使用备用函数工作,谢谢! –
欢迎您,欢迎回答有用!我的解释做了一个小小的修改:'%template(testMapPtr)shared_ptr'导致最初为空testMapPtr共享指针,但'%shared_ptr(testMap)'实际上创建了一个透明的shared_ptr,它已经用'testMap'实例初始化我会将其添加到答案中。 –
luart