2016-12-02 107 views
4

我有一個複雜的C++庫,我需要暴露給java android應用程序。這個C++庫由標準C++類和C++類模板組成。模板類包裝C++模板構造函數

庫中的模板之一有一個模板構造函數。

因爲一個例子是勝過千言萬語:

namespace NS1 { 

    template < class T > 
    class Bar { 

    protected: 

     T mVal; 

    public: 

     template< class OtherType > 
     Bar (const Bar<OtherType>& pOther) { 
      mVal = pOther.mVal; 
     } 

    }; 

    class A { 
    }; 

    class B : public A {}; 
} 

我用下面痛飲接口文件片段包裝這些:

%extend NS1::Bar<A> { 
    %template(Abar) NS1::Bar::Bar<NS1::A>; 
    %template(ABar) NS1::Bar::Bar<NS1::B>; 
}; 
%template(ABar) NS1::Bar<NS1::A>; 

%extend NS1::Bar<B> { 
    %template(BBar) NS1::Bar::Bar<NS1::B>; 
}; 
%template(BBar) NS1::Bar<NS1::B>; 

我想包裝,包括模板的包裝構造函數:

public class ABar { 
    public ABar (ABar other) {...} 
    public ABar (BBar other) {...} 
} 

這是好的,問題是擴展指令似乎忽略模板參數,並用這些擴展Bar模板的每個實例。即在BBar Java類看起來是這樣的:

public class BBar { 
    public BBar (ABar other) {...} 
    public BBar (BBar other) {...} 
} 

這是在這種情況下,不正確。

如何將「擴展」綁定到特定的模板實例?

注:

使用在%的命名空間擴展指令(%extend NS1::Bar<NS1::A>{...})引起痛飲斷言失敗。

我試圖與這兩個痛飲2.0.12和3.0.8

任何線索的人?

回答

1

我得到這個工作,因爲你希望與SWIG 3.x.這絕對是過於敏感,我認爲這歸結爲三件事:

  1. 與名稱空間保持一致。要麼始終使用完全限定版本,要麼始終在.i文件的命名空間中寫入所有內容。
  2. 請參閱Bar而不是Bar::Bar內部的%extend內的構造函數。 (根據std::pair example in the documentation
  3. 實例化所有模板,然後選擇性地進行擴展。

我不完全確定所有這些東西都是強制性的,但它們肯定足以使它在這裏工作。所以我的工作示例如下:

%module test 

%include "test.hh" 

%template(ABar) NS1::Bar<NS1::A>; 
%template(BBar) NS1::Bar<NS1::B>; 

namespace NS1 { 

%extend Bar<A> { 
    %template(ABar) Bar<A>; 
    %template(ABar) Bar<B>; 
}; 

%extend Bar<B> { 
    %template(BBar) Bar<B>; 
}; 
} // NS1 

隨着test.hh是你給複製的C++代碼逐字這會產生理智的Java/JNI。

下也將工作過,雖然,按照上述guidlines:

%module test 

%include "test.hh" 

%template(ABar) NS1::Bar<NS1::A>; 
%template(BBar) NS1::Bar<NS1::B>; 

%extend NS1::Bar<NS1::A> { 
    %template() Bar<NS1::A>; 
    %template() Bar<NS1::B>; 
}; 

%extend NS1::Bar<NS1::B> { 
    %template() Bar<NS1::B>; 
};