包装包含向量的模板类时如何让 SWIG 应用模板? [英] How to get SWIG to apply templates when wrapping a template class containing vectors?

查看:29
本文介绍了包装包含向量的模板类时如何让 SWIG 应用模板?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 SWIG 来包装(在 C# 中)一些包含模板类的 C++ 代码,该模板类本身包装了 std::vector.我在互联网上看到了关于如何声明向量类型模板的各种参考资料,但无法让它与额外的抽象层一起工作.这就是我在 interface.i 文件中所做的,例如:

I am trying to use SWIG to wrap (in C#) some c++ code that contains a template class that itself wraps a std::vector<T>. I have seen various references on the internet on how to declare the templates for the vector types, but can't get this to work with the extra layer of abstraction. This is what I am doing in the interface.i file for example:

// interface.i file    
%module myNamespaceWrapper
%{
#include "myVector.h"  
%}  

%include "myVector.h"
%include "std_string.i"
%include "std_vector.i"

namespace std {
%template(vector_MyType) vector<MyType*>;
%template(vector_Int) vector<int>;
}

namespace myNamespace {
%template(myVectorMyType) myVector<MyType*>;
%template(myVectorInt) myVector<int>;
}

虽然这似乎自己正确创建了相应的 C# 类型,但我尝试定义的 std::vector 模板并未应用于其他在内部使用它们的类,包括通过头文件的方式.为了向您展示我的意思,有一个 C++ 类,例如:

While this seems to create the corresponding C# types correctly by themselves, the std::vector templates that I have tried to define are not applied to other classes which use them internally, included by way of header files. To show you what I mean, there's a c++ class like:

// myVector.h
namespace myNamespace 
{    
    template<class T> 
    class myVector
    {

    private :
        std::vector<T> vect;

    public : 
        myVector(){}
        virtual ~myVector(){}

        virtual const std::vector<T> & getVect()
        {
            return vect;
        }

        virtual T& front()
        {
            return vect.front();
        }
    }
}

即使我得到了一个由 SWIG 创建的 vector_MyType 类,当它包装我的模板类时,它并没有使用它,而是提供了很多这样的例子:

Even though I get a vector_MyType class created by SWIG, when it wraps my template class it is not using it and instead giving lots of examples like this:

public class myVectorMyType : global::System.IDisposable {

    public virtual SWIGTYPE_p_p_myNamespace__MyType front() {
        SWIGTYPE_p_p_myNamespace__MyType ret = new SWIGTYPE_p_p_myNamespace__MyType(myNamespaceWrapperPINVOKE.myVectorMyType_front__SWIG_0(swigCPtr), false);
        return ret;
    }

    public virtual SWIGTYPE_p_myNamespace__std__vectorT_myNamespace__MyType_p_t getVect() {
        SWIGTYPE_p_myNamespace__std__vectorT_myNamespace__MyType_p_t ret = new SWIGTYPE_p_myNamespace__std__vectorT_myNamespace__MyType_p_t(myNamespaceWrapperPINVOKE.myVectorMyType_getVect(swigCPtr), false);
        return ret;
    }
}

请有人告诉我使用 MyTypevector_MyType 而不是 SWIGTYPE_p_myNamespace__std__vectorT_myNamespace__MyType_p_tSWIGTYPE_p_p_myNamespace__MyType 生成包装器时我缺少什么 ?

Please can someone advise what I am missing for SWIG to generate the wrapper using MyType and vector_MyType instead of SWIGTYPE_p_myNamespace__std__vectorT_myNamespace__MyType_p_t and SWIGTYPE_p_p_myNamespace__MyType ?

这是否与返回 T& 的模板 getVect() 函数有关,即我是否需要为 %template(myVectorInt) myVector 做任何不同的事情; 情况,其中 int 不是指针?

Is this anything to do with the template getVect() function returning T&, i.e. would I need to do anything differently for the %template(myVectorInt) myVector<int>; case, where int is not a pointer?

推荐答案

最后我意识到了我的错误,SWIG 按预期生成了类.

In the end I realised my mistake and SWIG generated the classes as expected.

// interface.i file    
%module myNamespaceWrapper
%{
#include "myVector.h"  
%}  

%include "myVector.h"
%include "std_string.i"
%include "std_vector.i"

namespace std {
%template(vector_MyType) vector<MyType*>;
%template(vector_Int) vector<int>;
}

namespace myNamespace {
// using namespace std; // don't include this!
%template(myVectorMyType) myVector<MyType*>;
%template(myVectorInt) myVector<int>;
}

这产生了如下类:

public class myVectorMyType : global::System.IDisposable {
  private global::System.Runtime.InteropServices.HandleRef swigCPtr;
  protected bool swigCMemOwn;

  ...

  public virtual vector_MyType getVect() {
    vector_MyType ret = new vector_MyType(myNamespaceWrapperPINVOKE.myVectorMyType_getVect(swigCPtr), false);
    return ret;
  }
}

其中底层 vector_MyType 与 std_vector.i 模板一致:

where the underlying vector_MyType is as per the std_vector.i template:

public class vector_MyType: global::System.IDisposable, global::System.Collections.IEnumerable
    , global::System.Collections.Generic.IList<MyType>
 {...}

这篇关于包装包含向量的模板类时如何让 SWIG 应用模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆