Как заставить SWIG применять шаблоны при упаковке класса шаблона, содержащего векторы?

Я пытаюсь использовать SWIG для переноса (на С#) кода С++, который содержит класс шаблона, который сам обертывает std::vector<T>. Я видел различные ссылки в Интернете о том, как объявлять шаблоны для типов векторов, но не может заставить это работать с дополнительным слоем абстракции. Это то, что я делаю в файле interface.i, например:

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

Хотя кажется, что они сами правильно создают соответствующие типы С#, шаблоны std::vector, которые я пытался определить, не применяются к другим классам, которые используют их внутренне, включая файлы заголовков. Чтобы показать вам, что я имею в виду, есть класс С++, например:

// 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();
        }
    }
}

Несмотря на то, что я получаю класс vector_MyType, созданный SWIG, когда он завершает мой класс шаблонов, он не использует его и вместо этого дает множество примеров, подобных этому:

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

Пожалуйста, кто-нибудь может сообщить, что мне не хватает для SWIG, чтобы создать обертку, используя MyType и vector_MyType вместо SWIGTYPE_p_myNamespace__std__vectorT_myNamespace__MyType_p_t и SWIGTYPE_p_p_myNamespace__MyType?

Это связано с тем, что функция getVect() шаблона возвращает T&, то есть мне нужно что-то сделать для случая %template(myVectorInt) myVector<int>;, где int не является указателем?

Ответы

Ответ 1

В конце я осознал свою ошибку, и SWIG сформировал классы, как ожидалось.

// 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:

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

Ответ 2

Я бы рекомендовал избежать проблемы и просто создать оболочку для каждого требуемого экземпляра:

class wrap_int : public temp <int>
{
};