SWIG JAVA 如何使用 %interface 和纯虚拟方法包装C++多重继承

SWIG JAVA how to wrap C++ multiple inheritance with %interface and pure virtual methods

本文关键字:方法 虚拟 包装 C++ 多重继承 JAVA 何使用 %interface SWIG      更新时间:2023-10-16

我在使用 SWIG 将大量C++代码包装到 JAVA 时遇到了问题。

我试图做的是包装一个 Derived 类,该类在 C++ 中扩展了其他 2 个类,但其中一个类(示例下面的 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 包装的内容。

当我在上面的例子上运行 Swig 时,它会创建 Base1 作为接口(它应该)

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

并声明(在 JAVA 中)扩展 Base2 并实现 Base1 的派生类(它也应该),但是,它不会在实现接口 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);
  }
}

因此,我遇到了SWIG生成的类(派生)的Java编译错误,该类没有实现其接口的所有方法(Base1)

我错过了什么?我已经阅读了文档,应该可以工作...

我的".i"文件:(使用 swig 3.0.10)

%module SOURCEI
%include <swiginterface.i>
%interface_impl(Space::Base1);
%{
#include "Source.h"
%}
%include "Source.h"

我正在使用 swig 3.0.2,它非常适合我。我没有文件swiginterface.i。我的Java安装有点搞砸了,所以我尝试使用Python和Ruby。对于这两种语言,我制作了一个略有不同的界面文件。

%module example
%{
  #define SWIG_FILE_WITH_INIT
  #include "Source.h"
%}
%interface_impl(Space::Base1);
%include "Source.h"

我配备了默认虚拟析构函数的头文件。

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

我刚刚用 Java 尝试过,我确实在派生中得到了一个方法

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

我编译以下内容

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