Native C++代碼和託管.NET代碼互操作並不是什麼難事, 資料也很多, 但是有些方法複雜繁瑣, 本文介紹了一種簡單的可行、支持動態加載的基於CLR的交互方法.
部分其它方法可參見 在 Visual C++/Native 代碼中調用.NET 程序集
微軟類似例子 C++/CLI wrapper for .NET assembly (CppCLINETAssemblyWrapper), 該例子與本文類似, 只是通過編譯期引用方式, 不支持動態加載.
1.首先是動態加載目標程序集和類:
try { auto assembly = Assembly::LoadFrom(L"RLib.dll"); // 加載 RLib.dll, 可指定路徑 auto type = assembly->GetType(L"RLib.Core", false, true); // 加載 RLib::Core 類型, 其中RLib是命名空間, Core是類名 if (type != nullptr){ // 類型加載成功, 上面代碼指定了類型加載失敗不引發異常, 某些case下這非常有用 // 注意此時 type 只是類對象, 並非實例 } //if } catch (Exception ^ex) { }
2.其次得到並調用類成員/方法, 本文以靜態成員爲例:
try { auto proc_init = type->GetMethod(L"Init"); // 取得 RLib::Core 類型的 public static int Init(int) 方法 auto params = gcnew array<Object ^, 1>(1); params[0] = gcnew Int32(1); // int參數, 顯式裝箱 auto ret = safe_cast<Int32 ^>(proc_init->Invoke(nullptr, params)); // 調用並取得返回值, 由於是靜態方法, 所以第一個參數指定爲 nullptr 即可 } catch (Exception ^ex) { }
#include <gcroot.h> static gcroot<Assembly ^> assembly = Assembly::LoadFrom(L"RLib.dll"); // 加載 RLib.dll, 可指定路徑 assembly->CodeBase; // 直接使用 -> 操作符訪問 assembly.operator Assembly ^ () == nullptr; // 判斷引用對象是否爲空, 這個需要顯式調用轉換
這只是最基本的交互方法, 更深層次的操作可以參閱MSDN文檔.