5

This question is in some ways an extension of the question posted here: SWIG_SHARED_PTR macro with templated class Although perhaps the issue is entirely unrelated.

The basic set up is this: I am trying to get SWIG to wrap a templated class as a shared_ptr. So the interface file should look something like this

%shared_ptr(template_instance)
%include template_class.cpp
%template(vector_instance) template_class<int>;

Now the problem is that template_class has a lot of derived classes, this causes a lot of warnings in swig, and then build errors. These classes do not need to be handled as shared_ptr's, so I would rather just ignore the warnings the above code generates. The solution to the error seems to be:

%shared_ptr(template_derived1)
%shared_ptr(template_derived2)
.
.
.
%shared_ptr(template_derivedn)
%shared_ptr(template_instance)
%include template_class.cpp
%template(vector_instance) template_class<int>;

This works, but is a huge mess, and I assume there must be some disadvantage to having everything represented as a shared_ptr (what is it?). Is there anyone around this?

EDIT: UPDATE WITH SPECIFIC EXAMPLE

test.h

class Base
{
  int base_member;
};

class Derived : public Base
{
  int derived_member;
};

test.i

%module test
%{
#include "test.h"
#include <boost/shared_ptr.hpp>
  %}

%include <boost_shared_ptr.i>
%shared_ptr(Base)
%include test.h

commands:

swig -python -c++ test.i 
g++ -fPIC -I /usr/include/python2.7 -c test_wrap.cxx

In this stripped down example, the swig call gives warnings, and the g++ call gives errors. Note that I've removed the templating, as it didn't seem to be an ingredient in the problem.

The errors are resolved by commenting out

%shared_ptr(Base)

The warning generated by swig is:

test.h:10: Warning 520: Derived class 'Derived' of 'Base' is not similarly marked as a smart pointer

and the error from g++ is:

test_wrap.cxx: In function ‘PyObject* _wrap_delete_Derived(PyObject*, PyObject*)’:
test_wrap.cxx:3155:22: error: ‘smartarg1’ was not declared in this scope
4

1 に答える 1

5

ここでの警告は、スマートポインターを有効に使用できるようにするために、基本クラスだけでなく、クラス階層全体についてSWIGに通知する必要があるためです。Baseスマートポインタをとるすべてのものが1を受け入れることができるように、スマートポインタ間で変換できる必要がありますDerived。したがって、インターフェイスファイルは次のようにする必要があります。

%module test
%{
#include "test.h"
#include <boost/shared_ptr.hpp>
%}

%include <boost_shared_ptr.i>
%shared_ptr(Base)
%shared_ptr(Derived)
%include "test.h"

これにより、警告された問題が解決され、私のマシンで正常にコンパイルされるコードが生成されました。

すべての派生型についてSWIGに伝えたくない場合、最も簡単なことは、型をSWIGから完全に非表示にすることです。つまり、Baseラップしたいものからのみ型を公開します。これはいくつかの方法で行うことができますが、最も邪魔にならないのは、インターフェイスファイルを次のように変更することです。

%module test
%{
#include "test.h"
#include <boost/shared_ptr.hpp>
%}

%include <boost_shared_ptr.i>
%ignore Derived;
%shared_ptr(Base)
%include "test.h"

これによりBase、ラップされるだけなので、コンパイルに失敗したコードはそれ以上生成されません。

または、タイプごとに必要な%ignoreため、ヘッダーファイルを変更して、の宣言/定義をDerivedSWIGから完全に非表示にすることができます。

class Base
{
  int base_member;
};
#ifndef SWIG
class Derived : public Base
{
  int derived_member;
};
#endif

%includeプロジェクトがタイプごとに1つのヘッダーファイルを持つように編成されている場合(大まかに) 、ベースファイル以外のファイルを使用しないことで、はるかに簡単な方法でこれを実行できる場合があります。

それでもそれらをラップしたいが、smart_ptrとしてではない場合は、たくさんあることを受け入れる必要があると思います%smart_ptr-おそらくそれらの生成を自動化できますか?モジュールを使ってゲームをプレイできるかもしれませんが、簡単で努力する価値はないと思います。

于 2012-07-11T06:34:24.397 に答える