Как заставить 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>
{
};