问题
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>;
}
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();
}
}
}
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;
}
}
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
?
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?
回答1:
I would recommend avoiding the issue and just create wrappers for each instantiation you need:
class wrap_int : public temp <int>
{
};
回答2:
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>;
}
This produced classes like:
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;
}
}
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>
{...}
来源:https://stackoverflow.com/questions/29699543/how-to-get-swig-to-apply-templates-when-wrapping-a-template-class-containing-vec