私はC++コードとC#コードの間に動作するCLIインターフェイスを持っています。このコードは正しく私はStartメソッドが含まれているインタフェースの実装を取得するためにCreateImplを呼び出すことができますデフォルトのAppDomain以外のC#関数呼び出しを使ってC++ポインタインターフェイスを整理する
-------------C++ Interface---------------
namespace cppns
{
class cppInterface
{
public:
virtual bool Start(const char *pcDir) = 0;
};
}
------Implementation of abstract C++ interface in same dll---------
namespace cppns
{
class cppimp : public cppInterface
private:
gcroot<MyInternalCSharpClass^> mInternalClassAccess;
public:
cppimp::cppimp()
{
mInternalClassAccess = gcnew MyInternalCSharpClass();
}
virtual bool cppimp::Start(const char *pcDir)
{
System::AppDomain ^appDom = AppDomain::CurrentDomain::get();
System::String ^strDomainName = appDom->FriendlyName;
mInternalClassAccess->Initalize(pcDir);
}
}
---------Method to create an instance of the class in a factory--------------
cppns::cppInterface *GetImplObject()
{
return new cppns::cppimp();
}
----------Factory class .h to allow C++ to get an instance of the cppimp class------
------The C++ code knows about the abstract interface by including the header file--
------FactoryExport is __declspec(dllexport) when compiled in dll and---------------
----- __declspec(dllimport) when used as a header file in exe that uses header------
class FactoryExport ClassFactory
{
public:
static cppns::cppInterface *CreateImpl();
};
----------Factory class .cpp to allow C++ to get an instance of the cppimp class------
cppns::cppInterface *ClassFactory::CreateImpl()
{
return GetImplObject();
}
:コードは次のようにC++抽象インタフェースを持っています。私の問題は、CLR/.NET全体のロードと実行をデフォルトのAppDomainではないAppDomainに強制しようとしていることです。私は、次のコードを使用して、二次のAppDomainを作成することができます。
CComPtr<ICorRuntimeHost> pRuntimeHost;
//Retrieve a pointer to the ICorRuntimeHost interface
HRESULT hr = CorBindToRuntimeEx(
L"v2.0.50727", //Retrieve last version before 4.0.
// NULL, //Retrieve latest version by default
L"wks",
STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN | STARTUP_CONCURRENT_GC,
CLSID_CorRuntimeHost,
IID_ICorRuntimeHost,
(void**)&pRuntimeHost.p
);
hr = pRuntimeHost->Start();
DWORD dwAppDomainId = 22;
WCHAR domainName[80 + 1];
swprintf(domainName, 80, L"%s-%ld",L"NoDefaultDomain", dwAppDomainId);
CComPtr<IUnknown> pUnknownAppDomain;
hr = pRuntimeHost->CreateDomainEx(domainName, NULL, NULL, &pUnknownAppDomain);
CComPtr<_AppDomain> pAppDomain;
hr = pUnknownAppDomain->QueryInterface(__uuidof(_AppDomain), (VOID**)&pAppDomain.p);
BSTR bstrFriendlyName;
hr = pAppDomain->get_FriendlyName(&bstrFriendlyName);
if (SUCCEEDED(hr))
{
_bstr_t bstrFriendlyNameWrap(bstrFriendlyName, false);
}
_bstr_t bstrAssemblyName("InteropCode");
CComPtr<_Assembly> pAssembly;
hr = pAppDomain->Load_2(bstrAssemblyName, &pAssembly);
BSTR bstrFullName;
hr = pAssembly->get_FullName(&bstrFullName);
if (SUCCEEDED(hr))
{
_bstr_t bstrFullNameWrap(bstrFullName, false);
std::cout << "Assembly name is: " << bstrFullNameWrap << "\n";
}
この二次アプリケーションドメイン内の私にcppnsへのインタフェースを返すために、工場:: cppInterfaceを得るためのすべての試みが失敗しました。私は実装されたインターフェイスへのポインタを返すC#クラスのセカンダリファクトリを作成しようとしました。そのため、アセンブリのInvoke呼び出しによって、残りのコードがアセンブリをロードしたAppDomainで実行されるようになりました。 Invokeは私のインターフェイス上の任意のタイプのC++ポインタにマップすることができないIDispatchポインタを返します。
namespace cppns
{
public ref class NetFactory
{
public:
NetFactory()
{
}
cppInterface *CreateInterop()
{
return GetImplObject();;
}
};
}
セカンダリAppDomainですべてを実行する別の方法、またはStartメソッドを呼び出す際に使用できるIDispatchポインターはありますか?