如何从 C# 调用 C++ 类

Posted

技术标签:

【中文标题】如何从 C# 调用 C++ 类【英文标题】:How to call C++ class from C# 【发布时间】:2011-01-24 04:41:24 【问题描述】:

我想我必须创建一个托管 C++ 代码来包装本机 C++。但是我在尝试包装函数参数中使用的数组时遇到问题,该数组的类型是在本机 C++ 中定义的。本机C++代码如下:

//unmanageCPP.h
class __declspec(dllexport) unmanageMoney

public:
    unmanageMoney(int a, int b)  rmb = a; dollar = b; 
    unmanageMoney()  rmb = 0; dollar = 0; 
    int rmb;
    int dollar;
;

class __declspec(dllexport) unmanageSum

public:
    //how to wrap this funciton?
    int addDollar(unmanageMoney a[], unmanageMoney b[]);
;

//unmanageCPP.cpp
#include "unmanaged.h"

int unmanageSum::adddollar(unmanageMoney a[], unmanageMoney b[])

    return a[0].dollar + b[0].dollar;

谁能告诉我如何编写manageCPP.h?非常感谢!

更新

我编写manageCPP.h如下,但我不知道怎么写addDollar()

//first, I wrap the class unmanageMoney for use in manageSum::addDollar()
public ref class manageMoney

private:
    unmanageMoney* mMoney;
public:
    unmanageMoney getMoney()
    
        return *mMoney;
    
    manageMoney(int a, int b)    mMoney = new unmanageMoney(a, b); 
    ~manageMoney()   delete mMoney; 
;

public ref class manageSum

    // TODO: Add your methods for this class here.
private:
    unmanageSum *mSum;
public:
    manageSum()
    
        mSum = new unmanageSum();
    
    ~manageSum()
    
        delete mSum;
    

    //it must be wrong if I code like this, for unmanageSun::adddollar() only
    // receives unmanageMoney as arguments. So what should I do?
    int adddollar(manageMoney a[], manageMoney b[])
    
            return mSum->adddollar(a, b);
    

;

【问题讨论】:

@CDBean 如果您对问题有更新或需要提供更多详细信息,请编辑您的原始问题以包含新数据。 您可能需要cli::array<manageMoney^> a 作为addDollar 的参数,这将在C# 中显示为manageMoney[] a 对于unmanagedSum::adddollar,您确定要unmanagedMoney a[] 而不是const unmanagedMoney& a?您似乎只想要数组中的第一项,而这可以通过引用(或指针)来完成。 @Ben Voigt 是的,我也发现了。但是那应该怎么处理这个论点呢?我当前的解决方案是创建另一个类型为 unmanageMoney 的数组,并从 array ^a 复制其值。有没有更简单的方法?顺便问一下,这里的“^”是什么意思? @Jonathan Sampson 谢谢提醒 【参考方案1】:

您使用

创建一个 C++/CLI 源文件
public ref class SomethingOrOther

    //...
;

并将编译选项设置为使用/clr 选项。

除此之外,它几乎与编写原生 C++ 相同。您将#include 要重用的类的头文件,创建实例并调用它们的成员函数,就像普通的 C++ 一样。但是ref class 中的任何内容对 C# 都是可见的。

而且你不要把__declspec(dllexport) 放在课堂上。永远不会。它对函数很有用,但与类一起使用时会产生痛苦。

【讨论】:

感谢您的回答,但是如果成员函数也具有在本机 C++ 中定义的参数类型怎么办?我也需要包装参数类型吗? @CDBean:是的。在本机类型和托管类型之间进行 1:1 映射并不总是有意义(有时将结构参数拆分为多个参数或类似的东西可能有意义),但您需要提供某种形式的转换. 而且我不知道为什么我不应该把 __declspec(dllexport) 放在课堂上。我尝试删除它,但结果是错误的,错误“缺少模块”

以上是关于如何从 C# 调用 C++ 类的主要内容,如果未能解决你的问题,请参考以下文章

如何编写我的 C++ 函数以便我可以从 C# 调用它?

如何使用 C# 从 C++ 应用程序获取调用堆栈?

如何中断从 c# interop 调用的 c++ 代码

C#调用C++导出类的一个实例

如何使用 p/invoke 终止从 C# 调用的 C++ 函数

如何从 c++ 项目中调用用 c# 创建的 dll 文件? [复制]