我試圖從非託管C++代碼中調用託管.NET代碼的最佳方法。我在我的C++應用程序中發現了有關Hosting .NET的信息,並且我可以創建一個pRuntimeHost並無任何問題地啓動它。從非託管代碼調用託管.NET代碼的最佳方式
ExecuteInDefaultAppDomain似乎非常有限,因爲我真的想發送一些參數並讓它返回一個信息結構。最明顯的選擇是使用COM方法,但目前的C#代碼並沒有真正設置爲與方法的接口。
無論哪種方式我想返回整數,字符串(char *)s,雙打和其他核心C++類型。雙方都有太多的代碼將C++轉換爲C#,並且使用Managed C++不是一個可接受的解決方案,因爲使用此C++代碼的其他組不希望爲了性能原因而開始使用託管代碼。
目標是儘可能少地修改現有的C++和C#代碼,但仍然使用C++中特定點的C#代碼中的方法,而不會對C++代碼的速度產生重大影響。
基於互聯網的啓動和關閉序列來承載.NET上找到的代碼爲:
#include "stdafx.h"
#include <metahost.h>
#pragma comment(lib, "mscoree.lib")
int _tmain(int argc, _TCHAR* argv[])
{
ICLRMetaHost *pMetaHost = NULL;
ICLRMetaHostPolicy *pMetaHostPolicy = NULL;
ICLRDebugging *pCLRDebugging = NULL;
HRESULT hr;
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost);
hr = CLRCreateInstance(CLSID_CLRMetaHostPolicy, IID_ICLRMetaHostPolicy, (LPVOID*)&pMetaHostPolicy);
hr = CLRCreateInstance(CLSID_CLRDebugging, IID_ICLRDebugging, (LPVOID*)&pCLRDebugging);
DWORD dwVersion = 0;
DWORD dwImageVersion = 0;
ICLRRuntimeInfo *pRuntimeInfo;
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID *)&pRuntimeInfo);
ICLRRuntimeHost * pRuntimeHost = NULL;
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID *)&pRuntimeHost);
hr = pRuntimeHost->Start();
DWORD dwRetCode = 0;
//hr = pRuntimeHost->ExecuteInDefaultAppDomain(argv[1], L"MyNamespace.MyClass", L"Message", L"Hello World!", &dwRetCode);
// Stop the CLR runtime and shutdown cleanly.
hr = pRuntimeHost->Stop();
hr = pRuntimeHost->Release();
hr = pRuntimeInfo->Release();
hr = pCLRDebugging->Release();
hr = pMetaHostPolicy->Release();
hr = pMetaHost->Release();
return 0;
}
之所以產生額外的AppDomain是,C++代碼已經被使用了一些東西默認的AppDomain,我不希望有我的其他.NET程序集與當前的代碼干擾,也避免有自己的東西與我的干擾。順便說一下,我設法使CLI層完美工作,但我仍然試圖弄清楚如何將整個CLI層置入單獨的不是默認AppDomain的AppDomain。 –
還沒有試圖自己做,但理論上這應該不成問題。我知道你的方案是從本地調用託管組件,對吧?有一個稱爲「線程升級」(google或bing)的功能,它會在本機線程首次嘗試執行託管代碼時,將原生線程提升爲託管線程。由於CLR不知道在哪個AppDomain中執行該方式的託管代碼,因此它會將其置入默認狀態。所以你必須明確地處理這個轉換,可能使用'msclr :: call_in_appdomain'函數家族。 –
我已經證明我在這個位置最終解決方案:http://stackoverflow.com/questions/10301727/marshalling-c-pointer-interface-back-though-c-sharp-function-call-in-a-non-def –