Лучший способ вызова управляемого кода .NET из неуправляемого кода - PullRequest
7 голосов
/ 07 декабря 2011

Я пытаюсь найти наиболее эффективный метод вызова управляемого кода .NET из неуправляемого кода C ++.Я нашел информацию о хостинге .NET в своем приложении C ++, и я могу создать pRuntimeHost и запустить его без проблем.

ExecuteInDefaultAppDomain кажется очень ограниченным, так как я действительно хочу отправить ему несколько параметров ипусть он вернет структуру информации.Наиболее очевидной альтернативой является использование COM-методов, но текущий код C # на самом деле не настроен как интерфейс с методами.

В любом случае я хочу вернуть целые числа, строки (char *) s, double и другое ядро ​​C ++.типы.С обеих сторон слишком много кода для преобразования C ++ в C #, и использование Managed C ++ не является приемлемым решением, поскольку другие группы, использующие этот код C ++, не хотят начинать использовать Managed-код по соображениям производительности.

Цель состоит в том, чтобы как можно меньше изменить существующий код 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;
}

Ответы [ 2 ]

5 голосов
/ 07 декабря 2011

Да, я согласен с Джоном.Вы действительно не хотите создавать новый экземпляр среды выполнения и размещать его явно.Во-первых, сантехника за этим плохо документирована и может измениться в будущих версиях.Во-вторых, C ++ / CLI был разработан, чтобы делать именно это наиболее эффективным и безопасным способом.

  1. Пишите собственные интерфейсы C ++, которые представляют требуемую функциональность .Net.*

    Настройка библиотеки DLL с поддержкой CLR, которая реализует собственные интерфейсы с использованием неуправляемых классов.Внутри их реализации вы можете создавать и получать доступ к типам CLR и сохранять переменные экземпляра в полях gcroot<T>.Используйте функцию взаимодействия clr для маршалирования между управляемым / неуправляемым кодом, google или bing для marshal_as.

  2. Предоставьте (неуправляемую) фабричную функцию, которая создает экземплярсоставная часть.Этот + неуправляемый интерфейс C ++ - это API, который увидит ваш нативный код.Используйте dll точно так же, как и неуправляемую dll.

3 голосов
/ 07 декабря 2011

Если это приемлемо, лучшим решением может быть создание управляемого C ++ dll, который находится между ними.Управляемый код C ++ - лучший / самый эффективный способ связать управляемый и неуправляемый код.

Вы действительно не хотите добавлять COM в смесь.Это значительно замедлит работу.

Кроме того, являются ли эти "причины производительности", чтобы избежать количественного определения управляемого кода?Это звучит как анекдот, брошенный, чтобы избежать чего-то, чего они просто не хотят.Кроме того, вы можете указать, что они уже используют управляемый код, поскольку C # находится в миксе.

...