使用swig生成std :: vector到java.util.Vector代码

我尝试用SWIG生成java代码

MyList.h中,我声明了一个名为_list的自定义列表对象

List _list; 

这个List类inheritance自vector

 class List : public vector 

在业务类中(在C ++中),我返回一个自定义对象列表

 List getMyList(){ .... return list; } 

所以我想生成java代码,我可以将这个C ++ List检索为java.util.List或java.util.Vector。

在我的swig.i文件中,我无法管理如何体现

 %typemap(jstype) List "java.util.Vector" namespace std { %template(CustomVector) vector; } 

任何类型的帮助如何配置此swig.i模板文件或一些示例代码生成java.util.List / Vector返回函数将不胜感激。

谢谢。

你真的不想用你的包装接口来触摸java.util.Vector ,因为每次你将它传入/传出一个函数时,你最终会复制存储或进行大量的复制操作。 (另请注意,通常在C ++中inheritance容器是奇怪的设计)。

而在Java中,“正确”的做法是从java.util.AbstractListinheritance。 这个答案是我对类似问题的旧答案的更通用的版本。

它适用于所有std::vector类型,而不仅仅是一个固定类型,并处理需要使用“autobox”自定义类型映射通过Objects访问的基元 。 它缺少对专门的std::vector ,但是如果需要它应该很容易添加。

 %{ #include  #include  %} %include  %include  namespace std { template class vector { public: typedef size_t size_type; typedef T value_type; typedef const value_type& const_reference; vector(); vector(size_type n); vector(const vector& o); size_type capacity() const; void reserve(size_type n); %rename(isEmpty) empty; bool empty() const; void clear(); void push_back(const value_type& x); %extend { const_reference get(int i) const throw (std::out_of_range) { return $self->at(i); } value_type set(int i, const value_type& VECTOR_VALUE_IN) throw (std::out_of_range) { const T old = $self->at(i); $self->at(i) = VECTOR_VALUE_IN; return old; } int32_t size() const { return $self->size(); } void removeRange(int32_t from, int32_t to) { $self->erase($self->begin()+from, $self->begin()+to); } } }; } // Java typemaps for autoboxing in return types of generics %define AUTOBOX(CTYPE, JTYPE) %typemap(autobox) CTYPE, const CTYPE&, CTYPE& "JTYPE" %enddef AUTOBOX(double, Double) AUTOBOX(float, Float) AUTOBOX(boolean, Boolean) AUTOBOX(signed char, Byte) AUTOBOX(short, Short) AUTOBOX(int, Integer) AUTOBOX(long, Long) AUTOBOX(SWIGTYPE, $typemap(jstype,$1_basetype)) %typemap(javabase) std::vector "java.util.AbstractList<$typemap(autobox,$1_basetype::value_type)>" %typemap(javainterface) std::vector "java.util.RandomAccess" %typemap(jstype) std::vector get "$typemap(autobox,$1_basetype)" %typemap(jstype) std::vector set "$typemap(autobox,$1_basetype)" %typemap(jstype) std::vector &VECTOR_VALUE_IN "$typemap(autobox,$1_basetype)" %typemap(javacode) std::vector %{ $javaclassname(java.util.Collection<$typemap(autobox,$1_basetype::value_type)> e) { this.reserve(e.size()); for($typemap(autobox,$1_basetype::value_type) value: e) { this.push_back(value); } } %} 

其中大部分与SWIG当前提供的默认std_vector.i非常相似,新位是重命名,扩展和扩展AbstractList并实现RandomAccess映射。 它还添加了一个带有其他Collection的构造函数 – 这是Java文档推荐的并且很容易实现。 (其他std::vector类型的重载速度快得多)。

我在另一个SWIG界面中测试了这个向量包装:

 %module test %include "vector.i" %template(DblVec) std::vector; %template(ByteVec) std::vector; %include  %template(StringVec) std::vector; %inline %{ struct foo {}; %} %template(FooVec) std::vector; 

我能够编译和运行:

 public class run { public static void main(String argv[]) { System.loadLibrary("test"); DblVec dv = new DblVec(100); for (int i = 0; i < 100; ++i) { dv.set(i,(double)i); } FooVec fv = new FooVec(1); fv.set(0, new foo()); for (double d: dv) { System.out.println(d); } } }