2016-12-02 79 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>; 
};