我遇到了一個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