Запуск .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 реализован.