我有一个带有“MyClass”类的非托管dll。 现在有没有办法用C#代码创建这个类的实例?要调用它的构造函数?我试过了,但是visual studio报告了一个错误消息,指出这个内存区域已损坏或者是什么。
提前致谢
答案 0 :(得分:20)
C#无法创建从本机Dll导出的类实例。您有两种选择:
创建C ++ / CLI包装器。这是.NET类库,可以作为对任何其他.NET项目的引用添加。在内部,C ++ / CLI类使用非托管类,通过标准C ++规则链接到本机Dll。对于.NET客户端,此C ++ / CLI类看起来像.NET类。
为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。
答案 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);
全部。