SWIG:使用带有shared_ptr的std :: map访问器?

时间:2017-07-31 15:47:55

标签: python c++ swig

我在SWIG生成的C ++类包装器中遇到了一个奇怪的问题,当std::map被包装为std::shared_ptr时,我似乎无法使用#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; } }; 的标准访问器函数}类型。我设法生成了一个MWE,它可以再现我观察到的奇怪行为。

TestMap.h

%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"

然后我的SWIG界面文件:

TestMap.i

import TestMap as tm

ft = tm.fooType.make_shared()
myTestMap = tm.testMap()

myTestMap[1] = ft

最后,我用来测试界面的测试脚本:

test_interface.py

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

当我检查myTestMapstd::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> > 对各自类别的引用:

%shared_ptr(TestMap)

现在对于奇怪的部分 - 如果我从SWIG接口文件中省略myTestMap声明并重新编译,则地图访问器(在 test_interface.py 中)很高兴。当我检查<TestMap.testMap; proxy of <Swig Object of type 'testMap *' at 0x7f8eceb50630> > 的类型时,它是:

testMap*

所以,有两个问题:

  1. 当我有SWIG对象指针引用(shared_ptr)时,为什么我的访问器调用正常工作,但是当我有std::shared_ptr< testMap > *引用时(例如shared_ptr)?
  2. 如果我的派生地图类型需要testMap*,我如何解决这个问题呢?
  3. 加分问题:如果我声明std::shared_ptr<testMap>类型存在shared_ptr,为什么SWIG会自动将testMap转换为 twitter= new TwitterFactory(cb.build()).getSingleton(); 类型}类型(即使它没有被初始化?)

1 个答案:

答案 0 :(得分:1)

第一次myTestMap = tm.testMap()创建透明的shared_ptr。所以myTestMap[1]是shared_ptr的透明解除引用,随后将值赋值给键 第二次myTestMap = tm.testMap()创建空std :: map,因此myTestMap[1]将值分配给地图的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)创建一个使用testMap默认构造函数初始化的完全透明的shared_ptr。