我有一个未托管的dll,其中有一个类"MyClass"。现在是否有一种方法可以在C#代码中创建这个类的实例?调用它的构造函数?我尝试了,但是Visual Studio报告了一个错误,错误信息为该内存区域已损坏或类似。
提前致谢
C#无法创建从本地Dll导出的类实例。您有两个选择:
创建C++/CLI包装器。这是一个.NET类库,可以作为参考添加到任何其他.NET项目中。在内部,C++/CLI类使用未管理的类进行操作,按照标准的C++规则链接到本地Dll。对于.NET客户端,这个C++/CLI类看起来像.NET类。
为C++类编写C包装器,并使用PInvoke在.NET客户端中使用。例如,过度简化的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(); }
// 为MyClass的每个公共方法编写包装器函数。 // 每个包装器函数的第一个参数应该是类实例。
CreateInstance、ReleaseInstance和GetData可以在C#客户端使用PInvoke声明并直接调用。void*参数应在PInvoke声明中声明为IntPtr。
new
和delete
不是C++的构造吗?看起来只是一个静态的C++ API。 - Rotem#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的lib文件。将dll和lib放在同一个目录中,并编译C++/CLI代码。在托管代码目录中放置本机dll和C++/CLI dll。在托管项目中引用C++/CLI项目。在托管代码中实例化C++/CLI类,如下所示:
ManagedOperationHelper obj = new ManagedOperationHelper();
double ret=obj.Sum(10, 20);
namespace MyNamespace {
public class Test {
[DllImport("TheNameOfThe.dll")]
public static extern void CreateMyClassInstance();
public void CallIt() {
CreateMyClassInstance(); // calls the unmanged function via PInvoke
}
}
}
class MyClass {
public: MyClass() { /** Constructor */ }
};
MyClass* staticObject;
extern "C" void CreateMyObjectInstance() {
staticObject = new MyClass(); // constructor is called
}
[DllImport(@"C:\mm_2008\liba.dll", EntryPoint = "??0CRls@fld@@QAE@ABV01@@Z", SetLastError = true, CallingConvention = CallingConvention.ThisCall)] 内部静态外部函数 CreateObserv(ref IntPtr p);
这段代码抛出了一个 AccessViolationException 异常:accessviolationexception attempted to read or write protected memory... - Evgeny007