将C++转换为C#:如何包装C++中的类,使模板类中的方法在C#中的派生类中可用
Swig C++ to C#: How to wrap classes from C++ to make methods from template class available in derived class in C#?
我在命名空间external::internal 中有模板类BaseMyPoint
它实现了公共方法X()、Y()、Z()和SetCoord()。
然后写入
typedef内部::BaseMyPoint MyPointd;
创建派生类MyPoint,该类使用公共继承MyPointd
两个类的描述都存储在文件"myPoint.h"中:
#pragma once
#ifdef MYPOINTSDLL_EXPORTS
#define MYPOINTSDLL_API __declspec(dllexport)
#else
#define MYPOINTSDLL_API __declspec(dllimport)
#endif
namespace external {
namespace internal {
template<typename T>
struct MyPointTraits;
template<>
struct MyPointTraits<double>
{
typedef double ValueType;
static ValueType CoincidenceTolerance() { return 1e-7; }
};
template<>
struct MyPointTraits<float>
{
typedef float ValueType;
static ValueType CoincidenceTolerance() { return 1e-7f; }
};
template<typename T>
class BaseMyPoint
{
public:
T myX;
T myY;
T myZ;
typedef typename MyPointTraits<T>::ValueType ValueType;
BaseMyPoint() {}
BaseMyPoint(ValueType theX, ValueType theY, ValueType theZ) :
myX(theX), myY(theY), myZ(theZ) {}
BaseMyPoint(const BaseMyPoint& theOther) :
myX(theOther.myX), myY(theOther.myY), myZ(theOther.myZ) {}
ValueType X() const { return myX; }
ValueType& X() { return myX; }
ValueType Y() const { return myY; }
ValueType& Y() { return myY; }
ValueType Z() const { return myZ; }
ValueType& Z() { return myZ; }
void SetCoord(ValueType theX, ValueType theY, ValueType theZ)
{
X() = theX;
Y() = theY;
Z() = theZ;
}
};
}
typedef internal::BaseMyPoint<double> MyPointd;
typedef internal::BaseMyPoint<float> MyPointf;
class MyPoint : public MyPointd
{
public:
MyPoint() {}
MyPoint(const MyPointd& theOther) : MyPointd(theOther) {}
};
}
写入接口文件"myPoint.i":
%module myPointsWrapper
%{
#include "myPoint.h"
using namespace external;
using namespace external::internal;
%}
%include <windows.i>
%include "myPoint.h"
在命令行中,我写道:C: \swig-csharp-C++-namespace pointspase-outdir C:\myPoints\myPointcs\Generated myPoint.i
在C#中,我们通过实例MyPoint aPoint:引用这些方法(X(),Y(),Z(),SetCoord()
using System;
using pointspase;
namespace myPointcs
{
class Program
{
static void Main(string[] args)
{
MyPoint aPoint = new MyPoint();
double x = 0.2, y = 0.3, z = 0.4;
aPoint.SetCoord(x, y, z);
double X = aPoint.X(), Y = aPoint.Y(), Z = aPoint.Z();
}
}
}
我有
错误CS1061"MyPoint"不包含"Z"的定义,并且没有接受第一个的扩展方法"Z"找不到"MyPoint"类型的参数(是否缺少using指令或程序集引用?)
错误CS1061"MyPoint"不包含"Y"的定义,并且没有接受第一个的扩展方法"Y"找不到"MyPoint"类型的参数(是否缺少using指令或程序集引用?)
错误CS1061"MyPoint"不包含"X"的定义,并且没有接受第一个的扩展方法"X"找不到"MyPoint"类型的参数(是否缺少using指令或程序集引用?)
错误CS1061"MyPoint"不包含"SetCoord"的定义,也没有扩展方法"SetCood"可以找到接受"MyPoint"类型的第一个参数(是否缺少using指令或程序集引用?)
如何在C#类MyPoint中提供这些方法?
提前感谢您的关注,基里尔
编辑1
以下是一个简单的例子,它清楚地表达了我的问题。
在"file.h"中,我写
template <typename T>
class myclass {
public:
T get() const { return 0; }
};
class myintclass : public myclass<int> {};
在"file.i"中我写
%template (myclassi) myclass<int>
当我编译接口文件时,我有警告:
warning 401: Base class 'myclass< int >' undefined.
warning 401: 'myclass< int >' must be defined before it is used as a base class.
因此,C#类myintclass不包含方法get()。如何将接口文件更改为get()方法已从类myintclass中提供?
在编辑中给定file.h
,正确声明所有内容有点棘手。理想情况下,模板应该位于myintclass
定义之外的单独标头中,但这里有一种经过测试的方法:
文件.i
%module test
%{
#include "file.h"
%}
// Process the template first
template <typename T>
class myclass {
public:
T get() const { return 0; }
};
// Tell SWIG to generate code for a template instance.
%template(myclassi) myclass<int>;
// Now that SWIG has code for the template instance,
// SWIG can generate code for classes using the template instance.
class myintclass : public myclass<int> {};
测试模块(我为Python生成):
>>> import test
>>> t=test.myclassi()
>>> t.get()
0
>>> t=test.myintclass()
>>> t.get()
0
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 在派生函数中指定void*参数
- 如何通过派生类函数更改基类中的向量
- 如何委托派生类使用其父构造函数?
- 如何使用单独文件中的派生类访问友元函数对象
- 派生类销毁的最佳实践是什么
- 如何使用基类指针引用派生类成员
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何引用基类的派生类?
- 存储模板类型以强制转换回派生<T>
- 需要从 istream 和 ostream 派生 iostream
- 在 C++ 中用派生类型重写成员函数
- 具有多个类、派生类的C++正向声明
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 如果基类包含双指针成员,则派生类的构造函数
- 为什么此派生对象无法访问基类的后递减方法?
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践