C ++,Java,Swig,shared_ptrs和模板化类

时间:2016-01-19 11:48:37

标签: java c++ c++11 swig shared-ptr

我有一个像这样的C ++类结构:

class Base {
  public:
    virtual int getValue1();
}

template<typename DATATYPE>
class BaseT : public Base {
  public:
    virtual DATATYPE getValue2();
}

class Derived1 : public BaseT<char> {
  public:
    char getValue2();
}

class Derived2 : public BaseT<std::string> {
  public:
    std::string getValue2();
}

为了这个例子,请假设通过任何算法在派生类的构造函数中初始化值1和2。

我有一个容器类,内部包含std::vector<std::shared_ptr<Base>>,其中包含Derived1Derived2个实例。

容器类还具有以下三个功能:

std::vector<std::shared_ptr<Base>> getAllInstances();
std::vector<std::shared_ptr<Derived1>> getDerived1Instances();
std::vector<std::shared_ptr<Derived2>> getDerived2Instances();

在早期版本的C ++代码中,这些函数只返回实例的向量,而不是实例指针的向量(相同的三个函数,只返回例如std::vector<Base>)。

通过使用以下SWIG指令,我成功地为这些函数生成了一个可用的Java接口(为简单起见,我省略了#include):

%include "std_vector.i"
%template(BaseList) std::vector<Base>;
%template(Derived1List) std::vector<Derived1>;
%template(Derived2List) std::vector<Derived2>;

%include "Base.h"
%include "BaseT.h"

%template(Derived1) BaseT<char>;
%template(Derived2) BaseT<std::string>;

%include "Derived1.h"
%include "Derived2.h"

但是现在,因为我更改了函数返回类型,所以我无法让我的Java代码再次运行。

我尝试了以下SWIG指令:

%include "std_vector.i"
%include "std_shared_ptr.i"

%template(BasePtr) std::shared_ptr<Base>;
%template(Derived1Ptr) std::shared_ptr<Derived1>;
%template(Derived2Ptr) std::shared_ptr<Derived2>;

%template(BaseList) std::vector<std::shared_ptr<Base>>;
%template(Derived1List) std::vector<std::shared_ptr<Derived1>>;
%template(Derived2List) std::vector<std::shared_ptr<Derived2>>;

%include "Base.h"
%include "BaseT.h"

%template(Derived1) BaseT<char>;
%template(Derived2) BaseT<std::string>;

%include "Derived1.h"
%include "Derived2.h"

SWIG在没有警告的情况下运行,生成的.cpp文件编译,并生成.java文件。

问题:我的例如Derived1List仅包含Derived1Ptr个实例,而且不包含任何访问实际数据的方法 - Derived1Ptr的唯一公开方法是delete

下一步:我尝试添加%shared_ptr

%include "std_vector.i"
%include "std_shared_ptr.i"

%shared_ptr(Derived1)
%shared_ptr(Derived2)

/* ... templates and includes as above ... */

这导致SWIG产生关于类BaseBaseT未被标记为智能指针的警告,但.cpp文件仍然编译。

Derived1List现在包含Derived1 - 我可以用来访问实际数据的实例(完美!),但每当我尝试访问时,Java程序都会遇到EXCEPTION_ACCESS_VIOLATION derived1.getValue1()(完全不完美......) - derived1.getValue2()效果很好。

下一步:也请投入%shared_ptr(Base)

结果:关于Base没有被标记为智能指针的警告消失了,关于BaseT的警告显然仍然存在。

.cpp文件不再编译:

swig_wrapper.cpp: In function 'void Java_swig_mytestlibJNI_delete_1Derived1(JNIEnv*, jclass, jlong)':
swig_wrapper.cpp:2000:26: error: 'smartarg1' was not declared in this scope
   (void)arg1; delete smartarg1;
                      ^

下一步:也请投入%shared_ptr(BaseT)

结果:SWIG不会打印任何警告。 .cpp文件不再编译,并输出类似于expected a type, got 'BaseT'批次错误。

所以 - 我的问题是,为了使共享指针的向量工作,我的定义文件应该如何?我错过了什么?

0 个答案:

没有答案