我尝试用SWIG生成java代码
在MyList.h中,我声明了一个名为_list的自定义列表对象
List<T*> _list;
Run Code Online (Sandbox Code Playgroud)
这个List类继承自vector
class List : public vector<T>
Run Code Online (Sandbox Code Playgroud)
在业务类中(在C++中),我返回一个自定义对象列表
List<MyObject> getMyList(){
....
return list;
}
Run Code Online (Sandbox Code Playgroud)
所以我想生成java代码,我可以在这里检索这个C++ List作为java.util.List或java.util.Vector.
在我的swig.i文件中,我无法管理如何体现
%typemap(jstype) List "java.util.Vector"
namespace std {
%template(CustomVector) vector<MyObject>;
}
Run Code Online (Sandbox Code Playgroud)
任何种类的帮助如何配置此swig.i模板文件或一些示例代码生成java.util.List/Vector返回函数将不胜感激.
谢谢.
Fle*_*exo 10
你真的不想接触java.util.Vector你的包装界面,因为每次你将它传入/传出一个函数时,你最终会复制存储或进行大量的复制操作.(另请注意,通常在C++中继承容器是奇怪的设计).
而在Java中,"正确"的做法是继承java.util.AbstractList.这个答案是我对类似问题的旧答案的更通用的版本.
它适用于所有std::vector类型,而不仅仅是固定类型和处理原语,需要使用"autobox"自定义类型映射通过对象访问.它缺少对专业版的支持std::vector<bool>,但如果需要,应该很容易添加.
%{
#include <vector>
#include <stdexcept>
%}
%include <stdint.i>
%include <std_except.i>
namespace std {
template<class T> 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);
}
}
%}
Run Code Online (Sandbox Code Playgroud)
其中大部分与SWIG当前提供的默认std_vector.i非常相似,新位是扩展AbstractList和实现的重命名,扩展和类型映射RandomAccess.它还添加了一个带有其他内容Collection的构造函数- 这是Java文档推荐的,并且很容易实现.(其他std::vector类型的过载速度要快得多).
我在另一个SWIG界面中测试了这个向量包装:
%module test
%include "vector.i"
%template(DblVec) std::vector<double>;
%template(ByteVec) std::vector<signed char>;
%include <std_string.i>
%template(StringVec) std::vector<std::string>;
%inline %{
struct foo {};
%}
%template(FooVec) std::vector<foo>;
Run Code Online (Sandbox Code Playgroud)
我能够编译和运行:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5612 次 |
| 最近记录: |