您並不是真的想用您的包裝界面觸碰java.util.Vector
,因爲每次您將其傳入/傳出某個功能時,您都將最終複製存儲或進行大量複製操作。 (還要注意,一般來說在C++中從容器繼承是奇怪的設計)。
取而代之在Java中,「正確的」事情是從java.util.AbstractList
繼承。這個答案是我的older answer to a similar question更通用的版本。
它適用於所有的std::vector
類型,不只是一個固定的類型,並處理primitives which need to be accessed via Objects使用「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);
}
}
%}
這其中大部分是相當類似於SWIG目前提供的默認std_vector.i,新位是重命名,擴展和延伸AbstractList
和實施RandomAccess
typemaps。它還增加了一個構造函數,它需要其他Collection
- 這是Java文檔推薦的,並且很容易完成。 (有其他std::vector
類型超載,這是太多更快)。
另我痛飲界面中測試了這個向量包裝:
%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>;
這讓我能夠編譯並運行:
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);
}
}
}
請看看 的http://堆棧溢出。COM /問題/ 1854335 /如何到創建-A-Java的類相似 - 交流 - 模板類 和 http://stackoverflow.com/questions/462297/how-使用的-classt式的Java – phantasmagoria
關於'的std :: VECTOR'繼承,看看[這個問題](http://stackoverflow.com/questions/4353203/thou-shalt-not-inherit-from -stdvector)。 – juanchopanza
好,讓我們說我不會使用/返回一個std ::向量,那麼我怎樣才能將一個對象列表從C++層傳遞到我的java層。的 –