Запуск .NET
Запуск управляемого кода (.NET C#) из неуправляемого (cpp)
Для запуска управляемого кода, нужно запустить .NET машину и передать ей параметры запуска кода. .NET машина выполнена а виде COM объекта и получается с помощью интерфейса IID_ICLRRuntimeHost. (https://msdn.microsoft.com/ru-ru/library/01918c6x(v=vs.110).aspx) Передача параметров для запуска .NET приложениея просходит с помощью метода ICLRRuntimeHost::ExecuteInDefaultAppDomain, куда передаются имя файла имя класса и метода для запуска. Метод должен быть с такой сигнатурой: public static int methodToLoad(String param). При этом при обычном запуске .NET приложения запускается private static void Main(string[] args). И с помощью ExecuteInDefaultAppDomain его не запустить(https://msdn.microsoft.com/ru-ru/library/ms164411(v=vs.110).aspx) Коды возвратов ExecuteInDefaultAppDomain: http://blogs.msdn.com/b/yizhang/archive/2010/12/17/interpreting-hresults-returned-from-net-clr-0x8013xxxx.aspx
ICLRMetaHost Предоставляет методы для определения, какие версии CLR установлены,
ICLRRuntimeHost Предоставляет методы, позволяющие основному приложению явным образом запускать и останавливать выполнение среды CLR для создания и настройки доменов приложения с целью доступа к домену по умолчанию и перечисления всех доменов, выполняемых в процессе. C дополнительным методом, позволяющим задать интерфейс управления основным приложением.
IHostControl Предоставляет методы для настройки загрузки сборок и определения интерфейсов размещения, поддерживаемых основным приложением. (DomainManager)
AppDomain -- изолированное окружение для запуска приложений
Таким образом можно .NET код запускать следующим образом: CLRCreateInstance( CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost ); pMetaHost->GetRuntime( L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*)&pCLRRuntimeInfo ); pCLRRuntimeInfo->GetInterface( CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pCLRRuntimeHost ); pCLRRuntimeHost->ExecuteInDefaultAppDomain( L"examplelibrary.dll", L"examplelibrary.ClassToLoad", L"methodToLoad", L"", &nRet );
У pCLRRuntimeHost можно получить CLRControl pCLRRuntimeHost->GetCLRControl(&pCLRControl); У которого есть методы для получения интерфейсов для мониторинга процессов CLR https://msdn.microsoft.com/ru-ru/library/ms164354(v=vs.110).aspx. Например ICLRDebugManager.
В чём проблема:
Если посмотреть код CLREventBase::CreateMonitorEvent,
synch.cpp
void CLREventBase::CreateMonitorEvent(SIZE_T Cookie)
...
IHostSyncManager *pManager = CorHost2::GetHostSyncManager(); if (pManager != NULL){
... hr = pManager->CreateMonitorEvent(Cookie,&pEvent); ... else { HANDLE h = UnsafeCreateEvent(NULL,FALSE,FALSE,NULL); ... } Т.е. При разных вариантах выбираются разные реализации CreateEvent. UnsafeCreateEvent -- это winapi функуция. Откуда же берётся IHostSyncManager.
А берётся он вот таким образом corhost.cpp HRESULT CorHost2::SetHostControl(IHostControl* pHostControl) pHostControl->GetHostManager(IID_IHostSyncManager,(void**)&syncManager) в
CorHost2 судя по всему -- это реализация IID_ICLRRuntimeHost2. MSDN, правда рассказывает только про IID_ICLRRuntimeHost, думаю, что работают они примерно одинаково.
Я не нашёл как же получить реализацию IHostControl в Windows. При этом она есть, например, у такого проекта -- https://code.google.com/p/hadesmem/ (Хешировщик),
Есть полная реализация IHostControl, вместе с его интерфейсами: https://github.com/ldematte/HostedPumpkin https://github.com/pwlodek/CodeGallery/tree/master/src/ClrHostingDemo/src/DemoHost3
Я не уверен, что IHostControl в Windows реализован.