class 的 Swig 包装器继承自专门的模板类型导致缺少方法
Swig wrapper for class inheriting from specialized template type results in missing methods
我正在使用 Swig 1.4.1 为 C# 项目包装一些 C++ 代码。
考虑一个文件中的以下代码 Foo.h.
#ifndef __Foo__
#define __Foo__
namespace Ogre
{
template<int foo, typename T> class FooBase
{
public:
int getFooBase() const
{
return 1;
}
};
struct FooSpecialized : public FooBase<4, double>
{
int getFooSpecialized() const
{
return 2;
}
};
class FooImpl : public FooSpecialized
{
public:
int getFooImpl() const
{
return 3;
}
};
}
#endif
为此,我在我的 Swig 接口文件中使用了以下内容。
%include "Foo.h"
因此,我可以访问方法 getFooSpecialized()
和 getFooImpl()
。但是 getFooBase()
不见了。
我在编译我的 Swig 接口文件时没有警告。
通过查看生成的 C# 文件可以很容易地看出这一点。有一个文件 FooSpecialized.cs 其中包含
public class FooSpecialized : global::System.IDisposable {
...
public int getFooFooSpecialized() {
int ret = OgrePINVOKE.FooSpecialized_getFooFooSpecialized(swigCPtr);
if (OgrePINVOKE.SWIGPendingException.Pending) throw OgrePINVOKE.SWIGPendingException.Retrieve();
return ret;
}
}
和FooImpl.cs其中包含
public class FooImpl : FooSpecialized {
...
public int getFooImpl() {
int ret = OgrePINVOKE.FooImpl_getFooImpl(swigCPtr);
if (OgrePINVOKE.SWIGPendingException.Pending) throw OgrePINVOKE.SWIGPendingException.Retrieve();
return ret;
}
}
到目前为止,我尝试了 %rename
和 %template
,但没有用。
我还阅读了有关拆分文件的信息,但这对我来说不是一个选项,因为它是我正在使用的第三方组件。
关键是%template
的用途和位置。按原样使用您的 Foo.h
,以下 test.i
文件有效:
%module test
%{
#include "Foo.h" // Adds Foo.h to the generated code.
%}
// Declare to SWIG the FooBase class interface.
namespace Ogre
{
template<int foo, typename T> class FooBase
{
public:
int getFooBase() const;
};
// Now that SWIG knows the template, declare an instantiation of
// the template you want to use.
%template(FooBase4dbl) FooBase<4,double>;
// Declare the class interfaces that uses the template instance
struct FooSpecialized : public FooBase<4, double>
{
int getFooSpecialized() const;
};
class FooImpl : public FooSpecialized
{
public:
int getFooImpl() const;
};
}
如果您愿意,可以重构 header 以减少代码重复:
FooBase.h
#ifndef __FooBase__
#define __FooBase__
namespace Ogre
{
template<int foo, typename T> class FooBase
{
public:
int getFooBase() const
{
return 1;
}
};
}
#endif
Foo.h
#ifndef __Foo__
#define __Foo__
#include "FooBase.h"
namespace Ogre
{
struct FooSpecialized : public FooBase<4, double>
{
int getFooSpecialized() const
{
return 2;
}
};
class FooImpl : public FooSpecialized
{
public:
int getFooImpl() const
{
return 3;
}
};
}
#endif
test.i
%module test
%{
#include "Foo.h"
%}
%include "FooBase.h"
%template(FooSpec) Ogre::FooBase<4,double>;
%include "Foo.h"
演示(我为 Python 设置):
>>> import test
>>> f=test.FooImpl()
>>> f.getFooBase()
1
我正在使用 Swig 1.4.1 为 C# 项目包装一些 C++ 代码。
考虑一个文件中的以下代码 Foo.h.
#ifndef __Foo__
#define __Foo__
namespace Ogre
{
template<int foo, typename T> class FooBase
{
public:
int getFooBase() const
{
return 1;
}
};
struct FooSpecialized : public FooBase<4, double>
{
int getFooSpecialized() const
{
return 2;
}
};
class FooImpl : public FooSpecialized
{
public:
int getFooImpl() const
{
return 3;
}
};
}
#endif
为此,我在我的 Swig 接口文件中使用了以下内容。
%include "Foo.h"
因此,我可以访问方法 getFooSpecialized()
和 getFooImpl()
。但是 getFooBase()
不见了。
我在编译我的 Swig 接口文件时没有警告。
通过查看生成的 C# 文件可以很容易地看出这一点。有一个文件 FooSpecialized.cs 其中包含
public class FooSpecialized : global::System.IDisposable {
...
public int getFooFooSpecialized() {
int ret = OgrePINVOKE.FooSpecialized_getFooFooSpecialized(swigCPtr);
if (OgrePINVOKE.SWIGPendingException.Pending) throw OgrePINVOKE.SWIGPendingException.Retrieve();
return ret;
}
}
和FooImpl.cs其中包含
public class FooImpl : FooSpecialized {
...
public int getFooImpl() {
int ret = OgrePINVOKE.FooImpl_getFooImpl(swigCPtr);
if (OgrePINVOKE.SWIGPendingException.Pending) throw OgrePINVOKE.SWIGPendingException.Retrieve();
return ret;
}
}
到目前为止,我尝试了 %rename
和 %template
,但没有用。
我还阅读了有关拆分文件的信息,但这对我来说不是一个选项,因为它是我正在使用的第三方组件。
关键是%template
的用途和位置。按原样使用您的 Foo.h
,以下 test.i
文件有效:
%module test
%{
#include "Foo.h" // Adds Foo.h to the generated code.
%}
// Declare to SWIG the FooBase class interface.
namespace Ogre
{
template<int foo, typename T> class FooBase
{
public:
int getFooBase() const;
};
// Now that SWIG knows the template, declare an instantiation of
// the template you want to use.
%template(FooBase4dbl) FooBase<4,double>;
// Declare the class interfaces that uses the template instance
struct FooSpecialized : public FooBase<4, double>
{
int getFooSpecialized() const;
};
class FooImpl : public FooSpecialized
{
public:
int getFooImpl() const;
};
}
如果您愿意,可以重构 header 以减少代码重复:
FooBase.h
#ifndef __FooBase__
#define __FooBase__
namespace Ogre
{
template<int foo, typename T> class FooBase
{
public:
int getFooBase() const
{
return 1;
}
};
}
#endif
Foo.h
#ifndef __Foo__
#define __Foo__
#include "FooBase.h"
namespace Ogre
{
struct FooSpecialized : public FooBase<4, double>
{
int getFooSpecialized() const
{
return 2;
}
};
class FooImpl : public FooSpecialized
{
public:
int getFooImpl() const
{
return 3;
}
};
}
#endif
test.i
%module test
%{
#include "Foo.h"
%}
%include "FooBase.h"
%template(FooSpec) Ogre::FooBase<4,double>;
%include "Foo.h"
演示(我为 Python 设置):
>>> import test
>>> f=test.FooImpl()
>>> f.getFooBase()
1