2017-11-09 11 views
0

残念ながら、生のポインタオブジェクトと共有ポインタオブジェクト/戻りメソッドの両方が混在しているC++クラスへのPythonインターフェイスを構築しようとしています。基本的に、このインタフェースでは、設計制約のために生ポインタを返す特定の関数が残っています(つまり、データ構造が下位階層、つまりA→B→Cを定義し、共有ポインタが下に移動し、巡回所有権を打破するためには、バックアップを向いポインタ)SWIG:生ポインタのベクトルと共有のptrsを返す

は、私はしかし、観察していますこれに伴う問題は、つまり、私は共有PTRテンプレートを導入するときということです。

%shared_ptr(fooType) 

その後SWIGはラップを知っています/ fooTypeのプロキシクラスを作成しますが、fooType*のプロキシクラスは作成しません。 (逆に、%shared_ptrマクロが含まれていない場合、SWIGは生ポインタのプロキシクラスを作成します)。

私の問題は以下のようになります。私は生のポインタオブジェクトのベクトルを返す必要があります。したがって、たとえば、ここに私のMWEです:

fooType.h

#include <iostream> 
#include <vector> 

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()); 
    } 
    static fooType* newPtr() { return new fooType(); } 
    static std::vector<fooType*> newVecPtr() { 
     std::vector<fooType*> retVec; 
     for(size_t i = 0; i < 3; ++i) { retVec.push_back(new fooType()); } 
    return retVec; 
    } 
}; 

fooType.i

%module fooType 

%include <std_map.i> 
%include <std_shared_ptr.i> 
%include <std_vector.i> 

%{ 
#include "fooType.h" 
%} 

%shared_ptr(fooType); 
%include "fooType.h" 

%template(fooVec) std::vector<fooType>; 
%template(fooPtrVec) std::vector<fooType*>; 

testFooType.py

import fooType as fooMod 

ft = fooMod.fooType.make_shared() 
ftPtr = fooMod.fooType.newPtr() 
fooVec = fooMod.fooType.newVecPtr() 

print(ftPtr) 
print(ft) 
print(fooVec) 

for foo in fooVec: 
    print(foo) 
    foo.printFoo() 

これは私与える:

<fooType.fooType; proxy of <Swig Object of type 'std::vector< fooType * >::value_type' at 0x7feab54b42a0> > 
<fooType.fooTypePtr; proxy of <Swig Object of type 'std::shared_ptr<fooType> *' at 0x7feab54b4240> > 
<fooType.fooPtrVec; proxy of <Swig Object of type 'std::vector< fooType * > *' at 0x7feab54b4210> > 
<fooType.fooType; proxy of <Swig Object of type 'std::vector< fooType * >::value_type' at 0x7feab54b4780> > 
FOO! 
<fooType.fooType; proxy of <Swig Object of type 'std::vector< fooType * >::value_type' at 0x7feab54b4c90> > 
FOO! 
<fooType.fooType; proxy of <Swig Object of type 'std::vector< fooType * >::value_type' at 0x7feab54b4780> > 
FOO! 

だから、は私が間違ってここで何をやっている:私はマクロ%shared_ptr(fooType)をコメントアウトした場合

<fooType.fooType; proxy of <Swig Object of type 'std::shared_ptr<fooType> *' at 0x7fd83ccfeb10> > 
<fooType.fooType; proxy of <Swig Object of type 'std::shared_ptr<fooType> *' at 0x7fd83ccfec30> > 
<fooType.fooPtrVec; proxy of <Swig Object of type 'std::vector< fooType * > *' at 0x7fd83ccfeba0> > 
<Swig Object of type 'fooType *' at 0x7fd834c1dba0> 
Traceback (most recent call last): 
    File "testFooType.py", line 13, in <module> 
    foo.printFoo() 
AttributeError: 'SwigPyObject' object has no attribute 'printFoo' 

、私が手に?言い換えれば、私は生のポインタの共有ポインタのプロキシクラスを同時に生成するようにSWIGに指示する方法はありますか?

as illustrated hereのようなものを使用する方法が必ずしもわからないことに注意してください。つまり、私がC++側で持っているインターフェイスに悩まされているからです(つまり、クラスを変更して継承enable_shared_from_this)。

ほとんどの場合、共有ポインタを有効にすると、なぜプロキシクラスの世代が狂ってしまうのか、それを回避する方法を知りたいと思います。 (私はポインタを解析してリストに戻すために自分のタイプマップを開発しようとしましたが、これは役に立たないようですが、私はまだ賛美できないSWIGオブジェクトで終わります。)

答えて

0

結局、私は、共有ポインタがラップされているときに(すなわち、%shared_pointer(fooType)マクロが有効になっている)SWIGに生ポインタのプロキシタイプを作成させる適切な方法を判断できませんでした。

解決方法私は、SWIGのラッパーメソッドを使用して新しい共有ポインタオブジェクトに生ポインタを複製することでした(this answer hereからインスピレーションを受けています)。つまり、暗黙のコピーコンストラクタ(fooType::fooType(fooType&))とstd::make_sharedを使用して、元の生ポインタの所有権を主張しようとしない新しいshared_ptr<fooType>オブジェクトを作成します(これは制御しません;したがって、共有ポインタそのポインタを解放しようとしています。)誰も、両方のためのプロキシクラスを作るためにSWIGを得るような生のポインタのための適切なタイプマップを開発するための提案がある場合(つまり、 /生のポインタオブジェクトと共有ポインタのメソッドを呼び出す)、私は確かに興味があります。その間には、並列共有ポインタを作成するのが実行可能な回避策であるようです。

関連する問題