[esto se está poniendo TLDR ... perdón ...]Determinar cuándo .NET está a punto de ser cargada en (no administrado) C++
Yo trabajo en una enorme C aplicación (en su mayoría) ++/MFC con cientos de archivos DLL ; es compatible con un mecanismo "add in" cargado dinámicamente a través de COM, por lo que los complementos se pueden desarrollar en .NET utilizando la interoperabilidad COM. Algunas funcionalidades nuevas y limitadas se desarrollan en .NET sin usar este mecanismo de "complemento" (aunque todavía está cargado dinámicamente); sin embargo, el usuario final puede decidir no usar esta característica. Por lo tanto, es posible que .NET no se cargue al inicio.
Pero, cuando .NET es cargado, necesito hacer algo de initialzation-NET específica (ajuste específicamente CurrentUICulture para que coincida con la interfaz de usuario nativa/no administrado).
Una solución es simplemente despejar y hacer esta inicialización de .NET cuando el código se las arregla para cargar ya sea la nueva funcionalidad de .NET o los complementos COM. Dada la naturaleza de esta aplicación, probablemente sea una solución al 95% (la mayoría de los usuarios utilizarán la nueva funcionalidad).
Pero no es infalible. Alguien podría "agregar" rápidamente la nueva funcionalidad .NET en cualquier momento construyendo un módulo con el indicador /clr (recuerde, esta es una gran aplicación).
Una solución más robusta (y obvia) es simplemente hacer que .NET se cargue al inicio a través de C++/CLI. Pero algunos de los desarrolladores de C++ acérrimos a los que todo el ciclo de byte y reloj importa no quieren hacer esto; algo comprensible ya que no es necesario configurar CurrentUICulture a menos que/hasta que se cargue .NET.
Otra posibilidad que pensé en enganchar LoadLibrary
y buscar mscorlib. Ahora sé que .NET está a punto de ser cargado por algún motivo, cárguelo de la forma habitual y realice la inicialización antes de que el otro código haga algo. Pero conectar LoadLibrary
(o cualquier otra cosa, para el caso) realmente no es algo que quiera hacer.
Entonces, ¿hay una manera fácil (mejor)/mejor de saber si .NET está a punto de cargarse?
Editar: Respuesta de LockClrVersion de Reed es bastante maldito cerca. El único inconveniente es que no funcionará si enlaza en una DLL/ensamblado de modo mixto.
// ClrAboutToLoad.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <MSCorEE.h>
// http://community.bartdesmet.net/blogs/bart/archive/2005/07/22/2882.aspx
FLockClrVersionCallback begin_init, end_init;
STDAPI hostCallback()
{
printf("hostCallback()\n");
// we're in control; notify the shim to grant us the exclusive initialization right
begin_init();
ICLRRuntimeHost *pHost = NULL;
HRESULT hr = CorBindToRuntimeEx(NULL, L"wks", STARTUP_SERVER_GC, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (PVOID*) &pHost);
hr = pHost->Start();
// mission completed; tell the shim we're ready
end_init();
return S_OK;
}
int _tmain(int argc, _TCHAR* argv[])
{
LockClrVersion(&hostCallback, &begin_init, &end_init);
//fnTheDLL();
HMODULE hModule = LoadLibrary(L"TheDLL");
FARPROC fp = GetProcAddress(hModule, "fnTheDLL");
typedef void (*fnTheDLL_t)();
fnTheDLL_t fnTheDLL = reinterpret_cast<fnTheDLL_t>(fp);
fnTheDLL();
FreeLibrary(hModule);
return 0;
}
¡Esto parece prometedor! –
Debería hacer exactamente lo que está buscando. No lo he implementado nunca, pero revisé toda la API de alojamiento de CLR para rastrearlo. –
Esto es casi perfecto; el único inconveniente es que debe asegurarse de que nada causa que el CLR se cargue antes de llamar a * LockClrVersion *. El "problema" es que el enlace en un ensamblaje de modo mixto carga el CLR, tiene que cargar dinámicamente el ensamblaje. –