【问题标题】:Wrapping C++ template constructors in template class在模板类中包装 C++ 模板构造函数
【发布时间】:2016-12-02 14:43:49
【问题描述】:

我有一个复杂的 c++ 库,我需要将其公开给 java android 应用程序。此 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 {};
}

我使用以下 swig 接口文件 sn-p 包装这些:

%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 模板的每个实例化。 IE。 BBar java 类如下所示:

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

在这种情况下这是不正确的。

如何将扩展“绑定”到特定的模板实例化?

注意:

在 %extend 指令 (%extend NS1::Bar&lt;NS1::A&gt;{...}) 中使用命名空间会导致 Swig 中的断言失败。

我已经尝试过 swig 2.0.12 和 3.0.8

有什么线索吗?

【问题讨论】:

    标签: java c++ templates swig


    【解决方案1】:

    我可以按照您希望的那样使用 SWIG 3.x。这里肯定是过于敏感了,我认为归结为三点:

    1. 与命名空间保持一致。要么始终使用完全限定版本,要么始终将命名空间内的所有内容写入 .i 文件。
    2. 在%extend 中将构造函数称为Bar 而不是Bar::Bar。 (根据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。

    按照上述指导方针,以下内容也可以使用:

    %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>;
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-31
      相关资源
      最近更新 更多