我有一个像这样的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>>
,其中包含Derived1
和Derived2
个实例。
容器类还具有以下三个功能:
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产生关于类Base
和BaseT
未被标记为智能指针的警告,但.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'
的批次错误。
所以 - 我的问题是,为了使共享指针的向量工作,我的定义文件应该如何?我错过了什么?