在c#中创建非托管c++对象

问题描述 投票:0回答:3

我有一个非托管 dll,其中有一个类“MyClass”。 现在有没有办法在 C# 代码中创建此类的实例?调用它的构造函数?我尝试过,但视觉工作室报告错误,并显示一条消息,表明该内存区域已损坏或其他内容。

提前致谢

c# .net c++ unmanaged
3个回答
23
投票

C# 无法创建从本机 Dll 导出的类实例。您有两个选择:

  1. 创建 C++/CLI 包装器。这是 .NET 类库,可以将其添加为任何其他 .NET 项目的引用。在内部,C++/CLI 类与非托管类一起工作,通过标准 C++ 规则链接到本机 Dll。对于 .NET 客户端,此 C++/CLI 类看起来像 .NET 类。

  2. 为 C++ 类编写 C 包装器,可供 .NET 客户端通过 PInvoke 使用。例如,过于简化的C++类:


    类 MyClass()
    {
    民众:
        MyClass(int n){数据=n;}
        ~MyClass(){}
        int GetData(){返回数据;}
    私人的:
        整数数据;
    };

此类的 C API 包装器:


    无效* 创建实例()
    {
        MyClass* p = new MyClass();
        返回p;
    }

    void ReleaseInstance(void* pInstance)
    {
        MyClass* p = (MyClass*)pInstance;
        删除p;
    }

    int GetData(void* pInstance)
    {
        MyClass* p = (MyClass*)pInstance;
        返回 p->GetData();
    }

    // 为每个 MyClass 公共方法编写包装函数。
    // 每个包装函数的第一个参数应该是类实例。

CreateInstance、ReleaseInstance 和 GetData 可以使用 PInvoke 在 C# 客户端中声明,并直接调用。 void* 参数应在 PInvoke 声明中声明为 IntPtr。


3
投票

解决方案是创建 C++/CLI 包装器,例如:

#include "DllExportClass.h"

public ref class ManagedOperationHelper
{
    public:

    double Sum(double add1, double add2)
    {
        CDllExportClass obj;
        double ret=obj.Sum(add1, add2);
        return ret;
    }

    double Mult(double mult1, double mult2)
    {
        CDllExportClass obj;
        double ret=obj.Mult(mult1, mult2);
        return ret;
    }
};

其中 CDllExportClass 是从本机代码导出的类。上面是 C++/CLI 的 .h。小心让我们找到这个 dll 的库。将dll和lib放在同一目录中并编译C++/CLI代码。在托管代码目录中放置本机dll和C++/CLI dll。在托管项目中放置 C++/CLI 项目的引用。在 maged 代码中实例化 C++/CLI 类,例如:

ManagedOperationHelper obj = new ManagedOperationHelper();
double ret=obj.Sum(10, 20);  

就这样了。


2
投票

您不能直接在 C# 中使用未托管的 C++ 代码。可以使用 PInvoke 来实现互操作性。 有很多与此主题相关的问题,特别是在调用以指针作为参数的函数时。

基本程序如下:

C#部分

namespace MyNamespace {
  public class Test {
    [DllImport("TheNameOfThe.dll")]
    public static extern void CreateMyClassInstance();
    
    public void CallIt() {
        CreateMyClassInstance(); // calls the unmanged function via PInvoke
    }
  }
}
    

C++部分

class MyClass {
  public: MyClass() { /** Constructor */ }
};

MyClass* staticObject;

extern "C" void CreateMyObjectInstance() {
   staticObject = new MyClass(); // constructor is called
} 
© www.soinside.com 2019 - 2024. All rights reserved.