如何在包装包含向量的模板类时让SWIG应用模板?
问题描述:
我想使用SWIG来包装(在C#中)一些C++代码,其中包含一个模板类,它本身包装std::vector<T>
。我在互联网上看到了各种关于如何为矢量类型声明模板的参考资料,但无法让它与额外的抽象层一起工作。这是我在例如interface.i文件正在做的:如何在包装包含向量的模板类时让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 {
%template(myVectorMyType) myVector<MyType*>;
%template(myVectorInt) myVector<int>;
}
虽然这似乎是由自己正确地创建相应的C#类,没有应用,我试图定义的std ::矢量模板到其他内部使用它们的类,通过头文件包含它们。为了向你展示我的意思,有一个C++类,如:
// 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
类,当它围绕我的模板类是不使用它,而是让许多像这样的例子:
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;
}
}
可以请别人指教一下我失踪痛饮生成使用MyType
和vector_MyType
代替SWIGTYPE_p_myNamespace__std__vectorT_myNamespace__MyType_p_t
和SWIGTYPE_p_p_myNamespace__MyType
包装?
这是什么与模板getVect()函数返回T&
,即我需要为%template(myVectorInt) myVector<int>;
情况做不同的事情,其中int
不是一个指针吗?
答
最终我意识到自己的错误,并痛饮生成的类如预期。
// 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>
{...}
答
我会建议避免这个问题,只需创建包装您需要的每个实例:
class wrap_int : public temp <int>
{
};
是否使用的是SWIG的版本?我试着用2.0.11和3.0.5的例子以及正确生成的C#源代码,例如:'public virtual vector_MyType getVect(){vector_MyType ret = new vector_MyType(myNamespaceWrapperPINVOKE.myVectorMyType_getVect(swigCPtr),false); return ret; }' –
谢谢你试用这个!我也使用3.0.5。既然你知道它的工作原理,我就能够用我的代码找到问题。这与我提出的问题并不完全相同,实际上我在'namespace myNamespace {}'部分有一个额外的'using namespace std;'引起了这个问题。删除它,它按预期工作。 – SWilliams
小心修复问题中的示例并将其写为答案? – Flexo