我有一个非托管dll,里面有一个“MyClass”类。 现在有办法在C#代码中创建这个类的实例吗?调用它的构造函数?我尝试过,但视觉工作室报告错误,并提示此内存区域已损坏或出现错误。在C#中创建非托管C++对象#
在此先感谢
我有一个非托管dll,里面有一个“MyClass”类。 现在有办法在C#代码中创建这个类的实例吗?调用它的构造函数?我尝试过,但视觉工作室报告错误,并提示此内存区域已损坏或出现错误。在C#中创建非托管C++对象#
在此先感谢
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可以在C#客户端使用的PInvoke声明,并且直接调用。 void *参数应在PInvoke声明中声明为IntPtr。
您不能在C#中直接使用unmanged 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
}
感谢大家,我讨厌承认它,但看起来除了编写包装外,没有别的办法。 – Evgeny007 2010-04-14 12:09:06
其他选项是使用compiler/crl标志编写托管C++。然后,您可以在同一个DLL中混合使用非托管和托管代码,然后在您的C#代码中使用简单的调用托管方法。它会生成sam IL代码,就像在代码中包装本机方法一样。快速入门http://www.codeproject.com/Articles/19354/Quick-C-CLI-Learn-C-CLI-in-less-than-minutes – 2015-11-12 07:48:45
的解决方案是创建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项目的参考。 Instanciate在C++/CLI类的恶意代码中是这样的:
ManagedOperationHelper obj = new ManagedOperationHelper();
double ret=obj.Sum(10, 20);
这一切。
你能发表你试过的吗? – SwDevMan81 2010-04-14 11:44:01
和错误消息? – Asher 2010-04-14 11:46:01
1) static void Main(string [] args) IntPtr p = new IntPtr(); Program.CreateObserv(ref p); } [的DllImport(@ “C:\ mm_2008 \ liba.dll”, 入口点= “?? 0CRls @ @@ FLD QAE @ @@ ABV01 Z”,SetLastError =真, CallingConvention = CallingConvention。ThisCall)] 内部静态extern void CreateObserv(ref IntPtr p); 此代码抛出AccessViolationException:accessviolationexception尝试读取或写入受保护的内存... – Evgeny007 2010-04-14 12:00:36