Swig 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#?

查看:38
本文介绍了Swig C++ 到 C#:如何从 C++ 包装类以使模板类中的方法在 C# 的派生类中可用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在命名空间 external::internal 中有模板类 BaseMyPoint

它实现了公共方法 X()、Y()、Z() 和 SetCoord().

然后写

typedef internal::BaseMyPoint MyPointd;

创建派生类 MyPoint,继承 MyPointd 和 public

两个类的描述都存储在myPoint.h"文件中:

#pragma once#ifdef MYPOINTSDLL_EXPORTS#define MYPOINTSDLL_API __declspec(dllexport)#别的#define MYPOINTSDLL_API __declspec(dllimport)#万一命名空间外部{命名空间内部{模板struct MyPointTraits;模板<>struct MyPointTraits{typedef double ValueType;静态 ValueType CoincidenceTolerance() { return 1e-7;}};模板<>struct MyPointTraits{typedef 浮点值类型;静态 ValueType CoincidenceTolerance() { return 1e-7f;}};模板类 BaseMyPoint{民众:T myX;我的Y;T myZ;typedef typename MyPointTraits::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;}值类型&X() { 返回 myX;}ValueType Y() const { return myY;}值类型&Y() { 返回 myY;}ValueType Z() const { return myZ;}值类型&Z() { 返回 myZ;}void SetCoord(ValueType theX, ValueType theY, ValueType theZ){X() = theX;Y() = Y;Z() = theZ;}};}typedef internal::BaseMyPoint;我的点;typedef internal::BaseMyPoint我的点f;类 MyPoint : 公共 MyPointd{民众:我的观点() {}MyPoint(const MyPointd& theOther) : MyPointd(theOther) {}};}

写入接口文件myPoint.i":

%module myPointsWrapper%{#include "myPoint.h"使用外部命名空间;使用命名空间外部::内部;%}%include %include "myPoint.h"

在命令行中我写:C:\swig -csharp -c++ -namespace pointspase -outdir C:\myPoints\myPointcs\Generated myPoint.i

在 C# 中,我们通过实例 MyPoint aPoint 来引用这些方法(X()、Y()、Z()、SetCoord()):

使用系统;使用点空间;命名空间 myPointcs{课程计划{static void Main(string[] args){MyPoint aPoint = new MyPoint();双 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 指令或程序集引用?)

错误 CS1061MyPoint"不包含SetCoord"的定义并且没有扩展方法SetCoord"可以找到接受类型为MyPoint"的第一个参数(您是否缺少 using 指令或程序集引用?)

如何使这些方法在 C# 类 MyPoint 中可用?

提前感谢您的关注,基里尔

编辑 1

这是一个简单的例子,清楚地表达了我的问题.

在file.h"中我写

template 类我的类{民众:T get() const { return 0;}};class myintclass : public myclass{};

在file.i"中我写

%template (myclassi) myclass

当我编译接口文件时出现警告:

warning 401: 基类 'myclass<;输入 >'不明确的.警告 401: 'myclass<;输入 >'必须在用作基类之前定义.

因此,C# 类 myintclass 不包含方法 get().如何将接口文件更改为已从类 myintclass 中提供 get() 方法?

解决方案

给定 file.h 在您的编辑中,正确声明所有内容有点棘手.理想情况下,模板应该位于与 myintclass 定义不同的标头中,但这里有一种经过测试的方法:

文件.i

%module 测试%{#include "file.h";%}//首先处理模板模板 类我的类{民众:T get() const { return 0;}};//告诉 SWIG 为模板实例生成代码.%template(myclassi) myclass;//现在 SWIG 有模板实例的代码,//SWIG 可以使用模板实例为类生成代码.class myintclass : public myclass{};

测试模块(我为 Python 生成):

<预><代码>>>>进口测试>>>t=test.myclassi()>>>t.get()0>>>t=test.myintclass()>>>t.get()0

I have template class BaseMyPoint in namespace external::internal

It implements public methods X(), Y(), Z() and SetCoord().

Then write

typedef internal::BaseMyPoint MyPointd;

Create derived class MyPoint, that inherits MyPointd with public

Description of both classes is stored in a file "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) {}
};

}

Write in interface file "myPoint.i":

%module myPointsWrapper

%{
#include "myPoint.h"
using namespace external;
using namespace external::internal;
%}

%include <windows.i>
%include "myPoint.h"

In command line I write: C:\swig -csharp -c++ -namespace pointspase -outdir C:\myPoints\myPointcs\Generated myPoint.i

In C# we referring to these methods ( X(), Y(), Z(), SetCoord() ) through an instance MyPoint aPoint:

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();
            }
        }
    }

And I have

Error CS1061 'MyPoint' does not contain a definition for 'Z' and no extension method 'Z' accepting a first argument of type 'MyPoint' could be found (are you missing a using directive or an assembly reference?)

Error CS1061 'MyPoint' does not contain a definition for 'Y' and no extension method 'Y' accepting a first argument of type 'MyPoint' could be found (are you missing a using directive or an assembly reference?)

Error CS1061 'MyPoint' does not contain a definition for 'X' and no extension method 'X' accepting a first argument of type 'MyPoint' could be found (are you missing a using directive or an assembly reference?)

Error CS1061 'MyPoint' does not contain a definition for 'SetCoord' and no extension method 'SetCoord' accepting a first argument of type 'MyPoint' could be found (are you missing a using directive or an assembly reference?)

How to make these methods available in the C# class MyPoint?

Thanks in advance for your attention, Kirill

EDIT 1

Here is the simple example that clearly expresses my problem.

In "file.h" I write

template <typename T>
class myclass {
public:
    T get() const { return 0; }
};

class myintclass : public myclass<int> {};

In "file.i" I write

%template (myclassi) myclass<int>

When I compile the interface file I have warnings:

warning 401: Base class 'myclass< int >' undefined.
warning 401: 'myclass< int >' must be defined before it is used as a base class. 

As a result, C# class myintclass does not contain method get(). How can I change the interface file to get () method has been made available from the class myintclass?

解决方案

Given file.h in your edit, it is a bit tricky to declare everything correctly. Ideally the template should be in a separate header than the myintclass definition, but here's a tested way to do it:

file.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> {};

Testing the module (I generated for Python):

>>> import test
>>> t=test.myclassi()
>>> t.get()
0
>>> t=test.myintclass()
>>> t.get()
0

这篇关于Swig C++ 到 C#:如何从 C++ 包装类以使模板类中的方法在 C# 的派生类中可用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆