2012-05-15 18 views
6

我嘗試生成痛飲的std ::向量java.util.Vector中的代碼生成與痛飲

Java代碼MyList.h我聲明的自定義列表對象調用_list

List<T*> _list; 

和名單類從載體

class List : public vector<T> 

繼承在商業類(在C++)我返回李定製的ST對象

List<MyObject> getMyList(){ 
    .... 
    return list; 
} 

所以我想生成Java代碼,我可以檢索這個C++列表作爲java.util.List的或java.util.Vector中。

我swig.i文件

我無法管理如何體現

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

任何幫助,如何配置此swig.i模板文件或一些示例代碼來生成一個java.util.List /矢量返回函數將不勝感激。

謝謝。

+0

請看看 的http://堆棧溢出。COM /問題/ 1854335 /如何到創建-A-Java的類相似 - 交流 - 模板類 和 http://stackoverflow.com/questions/462297/how-使用的-classt式的Java – phantasmagoria

+2

關於'的std :: VECTOR'繼承,看看[這個問題](http://stackoverflow.com/questions/4353203/thou-shalt-not-inherit-from -stdvector)。 – juanchopanza

+0

好,讓我們說我不會使用/返回一個std ::向量,那麼我怎樣才能將一個對象列表從C++層傳遞到我的java層。的 –

回答

10

您並不是真的想用您的包裝界面觸碰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); 
    } 
    } 
} 
+0

(用SWIG 2.0.4測試) – Flexo

+0

嗨。你還會推薦使用這個包裝器來代替SWIG的'std_vector.i'實現嗎?我只需要在我的情況下交換原始數組數據。謝謝! –

+0

@JesúsZazueta如果它只是一個原始數組我可能只是使用JNI數組接口來做到這一點,並採取一兩個副本。 (或者重新編寫代碼,以便它可以使用來自Java的借用緩衝區並共享相同的內存)。 – Flexo