Unmanaged C++コードからManaged .NETコードを呼び出す方法として、最も優れた方法を探しています。私はC++アプリケーション内で.NETのホスティングに関する情報を見つけました。問題なくpRuntimeHostを作成して起動できます。Managed .NETコードをUnmanagedコードから呼び出す最も良い方法
ExecuteInDefaultAppDomainは実際にはいくつかのパラメータを送信して情報の構造を返すので、非常に制限されているようです。最も明白な選択肢はCOMメソッドを使用することですが、現在のC#コードはメソッドとのインターフェースとして実際には設定されていません。
どちらの方法でも、整数、文字列(char *)、倍精度およびその他のコアC++型を返したいと思います。このC++コードを使用している他のグループは、パフォーマンス上の理由からマネージドコードを使用したくないため、C++をC#に変換するコードが多すぎ、Managed C++を使用することは受け入れられないソリューションです。
既存の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;
}
追加のAppDomainを作成する理由は、C++コードが既定のAppDomainを既にいくつかのものに使用していて、追加の.NETアセンブリを現在のコードに干渉させたくなく、また自分のものが私のものに干渉するのを避けるためです。 BTW私は完全にCLIのレイヤーを管理していますが、私はまだCLIレイヤー全体をデフォルトのAppDomainではない別のAppDomainに取得する方法を見つけようとしています。 –
まだ自分自身でそれを試みたことはありませんが、理論的にはこれは問題ではありません。あなたのシナリオはネイティブのものからマネージドコンポーネントに呼び出すことだと思います。 「スレッドのプロモーション」(googleまたはbing)という機能があり、マネージドコードを最初に実行しようとするたびにネイティブスレッドをマネージドスレッドに昇格させます。 CLRは、AppDomainという管理コードを実行する必要があるという考えを持っていないので、デフォルトの状態にします。したがって、おそらく 'msclr :: call_in_appdomain'ファミリの関数を使用して、その遷移を明示的に処理する必要があります。 –
私はこの場所で私の最終的な解決策を文書化しました:http://stackoverflow.com/questions/10301727/marshalling-c-pointer-interface-back-though-c-sharp-function-call-in-a-non-def –