2016-07-13 29 views
1

Ich habe ein Problem beim Einwickeln eines großen C++ - Code mit JAVA SWIG.SWIG JAVA, wie C++ mehrere Vererbung mit% Interface und rein virtuellen Methoden Wrap

Was ich versuche, ist Wrapped eine abgeleitete Klasse, die 2 andere Klassen in C++ erweitert, aber eine der Klassen (Base1 im Beispiel unten), sollte als eine Schnittstelle umgebrochen werden. (Um zu berücksichtigen, dass Java keine Mehrfachvererbung hat).

Ich habe das Problem gefunden und erstellt eine einfache C++ Code, der das Problem veranschaulichen:

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(); 
    }; 
} 

Der obige Code stellt dar, was ich in JAVA wickeln möchten.

Als ich Swig laufen auf dem obigen Beispiel, es Base1 als Schnittstelle erzeugt (wie es sein sollte)

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

und erklärt (in JAVA) die abgeleitete Klasse Base2 erstreckt und Base1 Umsetzung (wie es sollte auch), ABER, ist es nicht eine Java-Methode in der abgeleiteten Klasse, die die Schnittstelle Base1 (Method1 innerhalb Abgeleitet) die vollständige abgeleitete Java-Klasse generiert implementiert ist wie folgt:

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); 
    } 
} 

Und so, im stecken mit ein Java-Kompilierungsfehler einer SWIG-generierten Klasse (Derived), die nicht alle Methoden ihrer Schnittstelle (Base1) implementiert

Was fehlt mir? Ich habe die Dokumentation zu lesen und sollte funktionieren ...

Meine ".i" file: (mit swig 3.0.10)

%module SOURCEI 

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

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

folgt Wenn ich die „= 0“ für reine entfernen virtuell und entfernen Sie die Deklaration von method1 in Derived, es funktioniert. Aber für mein Projekt kann ich die ".h" s nicht ändern. 'Namespace Space { Klasse Base1 { public: virtuelles void Method1(); }; Klasse Base2 { public: virtuelle void Method2(); }; Klasse Abgeleitet: öffentlich Base1, öffentlich Base2 { }; } ' –

Antwort

1

Ich verwende swig 3.0.2 und es funktioniert perfekt für mich . Ich habe die Datei swiginterface.i nicht. Meine Java-Installation ist ein wenig vermasselt, also habe ich es mit Python und Ruby versucht. Für beide Sprachen habe ich eine etwas andere Schnittstellendatei erstellt.

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

%interface_impl(Space::Base1); 

%include "Source.h" 

Die Header-Datei, die ich mit default'ed virtuellen Destruktoren ausgestattet haben.

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(); 
    }; 
} 

Ich habe gerade versucht es mit Java und ich habe eine Methode erhalten innerhalb Abgeleitet

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

ich die oben kompilieren als

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

Vielen Dank für die Hilfe, aber ich versuche mit Ihrem .i und Ihrem .h und es gibt den gleichen Fehler. Ich habe swig 3.0.2 heruntergeladen und es erscheint der Fehler "Warnung 813: Warnung für Space :: Abgeleiteter Proxy: Base Space :: Base2 wird ignoriert. Mehrfache Vererbung wird in Java nicht unterstützt." Wie rufe ich swig auf der Kommandozeile auf? Ich verwende: swig.exe -package teste.sourcepackage -klein -v -outdir temp -C++ -java -o temp/SOURCEJAVA_wrap.cxx Quelle.i –

+0

Ich laufe auf Windows (Laden Sie die vorkompilierte Windows-Distribution herunter) –

+0

Das Problem gefunden .... es ist der "-small" -Befehl ... Ich habe es benutzt, weil mein Wrapper groß geworden ist und ich irgendwo gelesen habe, dass er den generierten Wrapper komprimiert hat ... aber er tut es mehr als das "-klein - Kompilieren Sie im virtuellen Eliminierungs- und Kompaktmodus" Ich denke, der "virtuelle Eliminierungs" -Teil ignoriert die rein virtuellen Methoden ... Ich habe "-klein" in "-kompakt" geändert und es scheint jetzt zu funktionieren !!! –