Native C++藉助CLR動態載入並呼叫.NET程式集
阿新 • • 發佈:2019-01-10
Native C++程式碼和託管.NET程式碼互操作並不是什麼難事, 資料也很多, 但是有些方法複雜繁瑣, 本文介紹了一種簡單的可行、支援動態載入的基於CLR的互動方法.
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.其次得到並呼叫類成員/方法, 本文以靜態成員為例:
3.至此我們已經完成基本的程式碼互動, 但是有時候我們需要儲存託管物件以便反覆呼叫而不是重複載入, 直接加static修飾是不行的, 編譯不過, 解決方案大致有兩種, 一是使用GCHandle, 二是使用gcroot, 後者是對前者的包裝, 十分簡便, 示例如下: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文件.