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

时间:2010-04-14 11:34:53

标签: c# .net c++ unmanaged

我有一个带有“MyClass”类的非托管dll。 现在有没有办法用C#代码创建这个类的实例?要调用它的构造函数?我试过了,但是visual studio报告了一个错误消息,指出这个内存区域已损坏或者是什么。

提前致谢

3 个答案:

答案 0 :(得分:20)

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

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

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

  3. 
        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。

答案 1 :(得分:2)

您不能直接在C#中使用无提示的C ++代码。可以使用PInvoke完成互操作性。有a lot of issues related to this topic,特别是在调用具有指针作为参数的函数时。

基本程序如下:

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
} 

答案 2 :(得分:2)

解决方案是创建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。注意让lib找到这个dll。将dll和lib放在同一目录中并编译C ++ / CLI代码。在托管代码目录中放置本机dll和C ++ / CLI dll。在托管项目中放入C ++ / CLI项目的引用。在maged代码中实现C ++ / CLI类,如:

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

全部。