Estoy tratando de encontrar el método de mejor rendimiento para llamar al código administrado .NET desde el código C++ no administrado. Encontré información sobre Hosting .NET dentro de mi aplicación C++ y soy capaz de crear un pRuntimeHost y comenzarlo sin ningún problema.La mejor manera de llamar al código administrado .NET desde el código no administrado
El ExecuteInDefaultAppDomain parece muy limitado, ya que realmente quiero enviarle algunos parámetros y hacer que devuelva una estructura de información. La alternativa más obvia es usar métodos COM, pero el código actual de C# no está realmente configurado como interfaces con métodos.
De cualquier forma quiero devolver enteros, cadenas (char *) s, dobles y otros tipos básicos de C++. Hay demasiado código en ambos lados para convertir el C++ a C# y el uso de C++ administrado no es una solución aceptable, ya que los otros grupos que usan este código C++ no quieren comenzar a usar el código Administrado por razones de rendimiento.
El objetivo es modificar el código C++ y C# existentes lo menos posible pero seguir usando métodos dentro del código C# en puntos específicos dentro de C++ sin afectar en gran medida la velocidad del código C++.
Sobre la base de código que se encuentra en Internet el arranque y apagado de la secuencia de acoger .NET es:
#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;
}
El motivo para crear un dominio de aplicación adicional es que el código C++ ya está usando el dominio de aplicación predeterminado para algunas cosas y no quiero que mis ensamblajes .NET adicionales interfieran con el código actual y también para evitar que sus elementos interfieran con el mío . Por cierto, me las arreglé para que la capa de la CLI funcionara a la perfección, pero aún estoy tratando de descubrir cómo hacer que toda la capa de la CLI se convierta en un dominio de aplicación separado que no es el dominio de la aplicación predeterminado. –
Aún no he intentado hacerlo yo solo, pero teóricamente esto no debería ser un problema. Entiendo que su escenario es llamar a un componente administrado desde uno nativo, ¿verdad? Hay una función llamada "promoción de subprocesos" (google o bing) que provoca que un subproceso nativo se promueva a uno administrado, siempre que primero intente ejecutar el código administrado. Como el CLR no tiene idea de qué AppDomain debe ejecutar el código administrado que se llama así, lo pone en el predeterminado. Por lo tanto, tendrá que manejar explícitamente esa transición, probablemente utilizando la familia de funciones 'msclr :: call_in_appdomain'. –
He documentado mi solución final en esta ubicación: http://stackoverflow.com/questions/10301727/marshalling-c-pointer-interface-back-though-c-sharp-function-call-in-a-non-def –