我有一個非託管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