如何让 SWIG 在包装包含向量的模板 class 时应用模板?
How to get SWIG to apply templates when wrapping a template class containing vectors?
我正在尝试使用 SWIG 包装(在 C# 中)一些包含模板 class 的 C++ 代码,该模板本身包装 std::vector<T>
。我在 Internet 上看到了有关如何为矢量类型声明模板的各种参考资料,但无法使其与额外的抽象层一起使用。这就是我在 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>;
}
虽然这似乎可以自己正确地创建相应的 C# 类型,但我尝试定义的 std::vector 模板并未应用于内部使用它们的其他 classes,顺便包含在内的头文件。为了向您展示我的意思,有一个 c++ class 像:
// 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
class,当它包装我的模板时 class 它并没有使用它而是给出了很多这样的例子:
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
生成包装器时缺少什么吗?
这是否与返回 T&
的模板 getVect() 函数有关,即我是否需要对 %template(myVectorInt) myVector<int>;
情况做任何不同的事情,其中 int
不是指针?
我建议避免这个问题,只为您需要的每个实例创建包装器:
class wrap_int : public temp <int>
{
};
最后我意识到我的错误,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>
{...}
我正在尝试使用 SWIG 包装(在 C# 中)一些包含模板 class 的 C++ 代码,该模板本身包装 std::vector<T>
。我在 Internet 上看到了有关如何为矢量类型声明模板的各种参考资料,但无法使其与额外的抽象层一起使用。这就是我在 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>;
}
虽然这似乎可以自己正确地创建相应的 C# 类型,但我尝试定义的 std::vector 模板并未应用于内部使用它们的其他 classes,顺便包含在内的头文件。为了向您展示我的意思,有一个 c++ class 像:
// 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
class,当它包装我的模板时 class 它并没有使用它而是给出了很多这样的例子:
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
生成包装器时缺少什么吗?
这是否与返回 T&
的模板 getVect() 函数有关,即我是否需要对 %template(myVectorInt) myVector<int>;
情况做任何不同的事情,其中 int
不是指针?
我建议避免这个问题,只为您需要的每个实例创建包装器:
class wrap_int : public temp <int>
{
};
最后我意识到我的错误,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>
{...}