2016-07-13 6 views
1

SWIGを使用してJAVAに巨大なC++コードをラップしながら、私は問題を抱えているとC++の多重継承をラップする方法について説明します。SWIG JAVA%のインターフェースと、純粋仮想メソッド

私がしようとしているのは、C++で他の2つのクラスを拡張するDerivedクラスをラップすることですが、クラスの1つ(例ではBase1)はインターフェイスとしてラップする必要があります。 (複数の継承を持たないJavaを考慮する)

私は問題を発見したと問題を示す単純なC++コードを作成しました:

namespace Space { 
    class Base1 { 
     public: 
    virtual void Method1() = 0; 
    }; 
    class Base2 { 
    public: 
    virtual void Method2(); 
    }; 
    class Derived : public Base1, public Base2 { 
    public: 
    virtual void Method1(); 
    }; 
} 

上記のコードは、私はJAVAでラップしたいものを表します。

Iは、上記の例でガブガブ飲むを実行すると(それが必要ように)、それはインタフェースとしてBASE1を作成

public interface Base1 { 
    long Base1_GetInterfaceCPtr(); 
    void Method1(); 
} 

と派生クラスがBASE2を拡張し、BASE1を実装する(JAVAで)宣言(それはまた必要として)、しかしは、それはインターフェースBASE1を実装派生クラス内のJavaメソッドを作成しません(方法1は、内部の派生)以下のように生成された完全な派生Javaクラスは次のとおりです。

public class Derived extends Base2 implements Base1 { 
    private transient long swigCPtr; 

    protected Derived(long cPtr, boolean cMemoryOwn) { 
    super(SOURCEIJNI.Derived_SWIGUpcast(cPtr), cMemoryOwn); 
    swigCPtr = cPtr; 
    } 

    protected static long getCPtr(Derived obj) { 
    return (obj == null) ? 0 : obj.swigCPtr; 
    } 

    protected void finalize() { 
    delete(); 
    } 

    public synchronized void delete() { 
    if (swigCPtr != 0) { 
     if (swigCMemOwn) { 
     swigCMemOwn = false; 
     SOURCEIJNI.delete_Derived(swigCPtr); 
     } 
     swigCPtr = 0; 
    } 
    super.delete(); 
    } 

    public long Base1_GetInterfaceCPtr() { 
    return SOURCEIJNI.Derived_Base1_GetInterfaceCPtr(swigCPtr); 
    } 

    public Derived() { 
    this(SOURCEIJNI.new_Derived(), true); 
    } 
} 

をそしてそう、Imはで立ち往生そのインターフェイスのすべてのメソッドを実装していないSWIG生成されたクラス(派生)(BASE1)

のJavaコンパイル・エラー、私は何をしないのですか?私は、ドキュメントを読んだと...動作するはず

マイ「.I」ファイル:

%module SOURCEI 

%include <swiginterface.i> 
%interface_impl(Space::Base1); 

%{ 
#include "Source.h" 
%} 
%include "Source.h" 
+0

を次のように私は上記をコンパイルし、私はただのJavaでそれを試してみましたが、私は方法が内部

public void Method1() { exampleJNI.Derived_Method1(swigCPtr, this); } 

を派生のですか仮想化し、導出のmethod1の宣言を削除、それは動作します。しかし私のプロジェクトでは、 ".h"を変更することはできません。 '名前空間のスペース{ クラスBASE1 { 公共: 仮想無効方法1(); }; クラスBASE2 { 公共: 仮想ボイド方法2(); }; クラス派生:パブリックBase1、パブリックBase2 { }; } ' –

答えて

1

私はSWIG 3.0.2を使用していますが、それは私のために完璧に動作します(SWIG 3.0.10を使用して) 。私は、ファイルswiginterface.iを持っていません。私のJavaのインストールは少し台無しので、私は、PythonとRubyでみましたです。どちらの言語でも、私はわずかに異なるインターフェースファイルを作っています。

%module example 
%{ 
    #define SWIG_FILE_WITH_INIT 
    #include "Source.h" 
%} 

%interface_impl(Space::Base1); 

%include "Source.h" 

私はdefault'ed仮想デストラクタを装備しています。

namespace Space { 
    class Base1 { 
    public: 
    virtual void Method1() = 0; 
    virtual ~Base1() = default; 
    }; 
    class Base2 { 
    public: 
    virtual void Method2(); 
    virtual ~Base2() = default; 
    }; 
    class Derived : public Base1, public Base2 { 
    public: 
    virtual void Method1(); 
    }; 
} 

私は純粋なため、「= 0」を削除した場合

swig -java -c++ Source.i 
g++ -std=c++11 -fPIC -c Source.cpp Source_wrap.cxx -I/usr/lib/jvm/java-7-openjdk-amd64/include/ 
g++ -std=c++11 -fPIC -shared Source.o Source_wrap.o -o libShared.so 
+0

助けてくれてありがとうが、私はあなたの.iとあなたの.hを試してみて、同じエラーが出ます。私はswig 3.0.2をダウンロードし、 "Warning 813:Space for Warning :: Derived proxy:Base Space :: Base2を無視しました"というエラーメッセージを表示します。複数の継承はJavaではサポートされていません。" コマンドラインでswigを呼び出すにはどうすればいいですか? 私は以下を使用します: swig.exe -package teste.sourcepackage -small -v -outdir temp -C++ -java -o temp/SOURCEJAVA_wrap.cxx Source.i –

+0

ウィンドウが開きます(プリコンパイル済みのWindowsディストリビューションをダウンロードしてください) –

+0

問題を発見しました... "小さな"コマンド...ラッパーが大きくなったために使用しましたが、生成されたラッパーを圧縮した場所を読みました...それよりも " - 小さな - 仮想排除とコンパクトモードでコンパイル"私は "仮想排除"部分は純粋な仮想メソッドを無視していると思う...私は "-small"を "-fcompact"に変更し、 !!! –

関連する問題