创建非托管 c++ C# 中的对象

发布于 2024-08-29 00:53:24 字数 121 浏览 5 评论 0原文

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

提前致谢

I have an unmanaged dll with a class "MyClass" in it.
Now is there a way to create an instance of this class in C# code? To call its constructor? I tried but the visual studio reports an error with a message that this memory area is corrupted or something.

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

天冷不及心凉 2024-09-05 00:53:24

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

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

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

    class MyClass()
    {
    public:
        MyClass(int n){data=n;}
        ~MyClass(){}
        int GetData(){return data;}
    private:
        int data;
    };

该类的C API包装器:

    void* CreateInstance()
    {
        MyClass* p = new MyClass();
        return p;
    }

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

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

    // Write wrapper function for every MyClass public method.
    // First parameter of every wrapper function should be class instance.

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

C# cannot create class instance exported from native Dll. You have two options:

  1. Create C++/CLI wrapper. This is .NET Class Library which can be added as Reference to any other .NET project. Internally, C++/CLI class works with unmanaged class, linking to native Dll by standard C++ rules. For .NET client, this C++/CLI class looks like .NET class.

  2. Write C wrapper for C++ class, which can be used by .NET client with PInvoke. For example, over-simplified C++ class:

    class MyClass()
    {
    public:
        MyClass(int n){data=n;}
        ~MyClass(){}
        int GetData(){return data;}
    private:
        int data;
    };

C API wrapper for this class:

    void* CreateInstance()
    {
        MyClass* p = new MyClass();
        return p;
    }

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

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

    // Write wrapper function for every MyClass public method.
    // First parameter of every wrapper function should be class instance.

CreateInstance, ReleaseInstance and GetData may be declared in C# client using PInvoke, and called directly. void* parameter should be declared as IntPtr in PInvoke declaration.

被你宠の有点坏 2024-09-05 00:53:24

解决方案是创建 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);  

就这样了。

The solution is create C++/CLI wrapper like:

#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;
    }
};

where CDllExportClass is the class exported from native code. Above is the .h of the C++/CLI. Take care to let find the lib to this dll. Put the dll and the lib in the same directory and compile the C++/CLI code.In the managed code directory put the native dll and the C++/CLI dll. In the managed project put the reference of the C++/CLI project. Instanciate in the maged code the C++/CLI class like:

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

It's all.

仄言 2024-09-05 00:53:24

您不能直接在 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
} 

You can not use unmanged C++ code directly in C#. The interoperability can be done using PInvoke. There are a lot of issues related to this topic, especially when calling functions which have pointers as arguments.

The basic procedure goes like this:

C# part

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

C++ part

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

MyClass* staticObject;

extern "C" void CreateMyObjectInstance() {
   staticObject = new MyClass(); // constructor is called
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文