Я создал C++ DLL (он должен быть на C++), который динамически связывает DLL .Net для размещения сервера веб-сервисов. DLL .Net передает вызовы веб-службы на C++ DLL, которые, как оцениваются и отвечают также через DLL .Net.loadFromRemoteSources в проекте C++
Нечто подобное:
HSPWebService.DLL
-----------------------------------
HSPProxy.DLL | HSPWebServiceLib.DLL
-----------------------------------
HSPSendData.DLL
- HSPWebService.DLL - собственно C++ DLL.
- HSPProxy.DLL - прокси, сгенерированный компилятором MIDL через интерфейс HSP.DLL MIDL.
- HSPWebServiceLib.DLL - typelib, сгенерированный tlmbimp над HSP.DLL.
- HSPSendData.DLL - .Net DLL, которая включает в себя сервер веб-службы
Все работает как шарм. Проблема в том, что DLL-файлы находятся в сетевом ресурсе (// myPc/share). В моем журнале приложений отображается ошибка 0x80131515:
CreateAssemblyInstance ERROR: Не удалось создать экземпляр сборки. (hr = 80131515)
В моем исследовании я обнаружил, что ошибка 0x80131515 возникает из-за того, что инфраструктура .Net по умолчанию не загружает сборки из внешних источников. Для проектов .Net опция может быть задана в настройках проекта. Но у меня есть проект на C++ в Visual Studio 2010, и я не имею понятия об использовании этой конфигурации в моем проекте (или моем коде). Есть идеи?
Функция CreateAssemblyInstance:
HRESULT CHSPWebServiceObjectHost::CreateAssemblyInstance(_AppDomain* pDefAppDomain, CComPtr<IDispatch>& spDisp, LPCTSTR pszAsseblyName, LPCTSTR pszClassNameWithNamespace) const
{
spDisp = NULL;
REQUIRE_IN_POINTER(pDefAppDomain);
try
{
_bstr_t _bstrAssemblyName(pszAsseblyName);
_bstr_t _bstrszClassNameWithNamespace(pszClassNameWithNamespace);
//Creates an Assembly instance
CComPtr<_ObjectHandle> spObjectHandle;
HRESULT hr = pDefAppDomain->CreateInstanceFrom(_bstrAssemblyName, _bstrszClassNameWithNamespace, &spObjectHandle);
if (FAILED(hr))
{
Log(logDriver, _T("CHSPWebServiceObjectHost::CreateAssemblyInstance ERROR: Could not create an assembly instance. (hr=%08X)"), hr);
return hr;
}
CComVariant VntUnwrapped;
hr = spObjectHandle->Unwrap(&VntUnwrapped);
if (FAILED(hr))
{
Log(logDriver, _T("CHSPWebServiceObjectHost::CreateAssemblyInstance ERROR: Could not unwrap assembly object. (hr=%08X)"), hr);
return hr;
}
spDisp = VntUnwrapped.pdispVal;
}
catch (_com_error& e)
{
return e.Error();
}
return S_OK;
}
Это называется функцией StartCLR:
HRESULT CHSPWebServiceObjectHost::StartCLR(CComPtr<ICorRuntimeHost>& spRuntimeHost, CComPtr<IDispatch>& spDispHost) const
{
spRuntimeHost = NULL;
spDispHost = NULL;
//Retrieve a pointer to the ICorRuntimeHost interface
HRESULT hr = CorBindToRuntimeEx(L"v4.0.30319",
L"wks",
STARTUP_LOADER_SAFEMODE | STARTUP_CONCURRENT_GC,
CLSID_CorRuntimeHost,
IID_ICorRuntimeHost,
(void**)&spRuntimeHost);
if (FAILED(hr))
{
Log(logDriver, _T("CHSPWebServiceObjectHost::StartCLR ERROR: Could not load CLR into unmanaged host process. ( hr=%08X)"), hr);
return hr;
}
//Start the CLR
hr = spRuntimeHost->Start();
if (FAILED(hr))
{
Log(logDriver, _T("CHSPWebServiceObjectHost::StartCLR ERROR: Could not start CLR. (hr=%08X)"), hr);
return hr;
}
//Retrieve the IUnknown default AppDomain
CComPtr<IUnknown> spUnknown;
hr = spRuntimeHost->GetDefaultDomain(&spUnknown);
if (FAILED(hr))
{
Log(logDriver, _T("CHSPWebServiceObjectHost::StartCLR ERROR: Could not retrieve pointer to domain interface. ( hr=%08X)"), hr);
return hr;
}
CComQIPtr<_AppDomain> spDefAppDomain(spUnknown);
if (spDefAppDomain == NULL)
return E_NOINTERFACE;
CString strAssemblyFullPath = _T(".\\HSPSendData.dll");
return CreateAssemblyInstance(spDefAppDomain, spDispHost, strAssemblyFullPath, _T("Elipse.HSPWebService. HSPWebServiceHost"));
}
Примечание: 'CorBindToRuntimeEx' [устарел] (http://msdn.microsoft.com/en-us/library/99sz37yh (v = vs.100) .aspx). См. [Загрузка выполнения Common Language Runtime в процесс] (http://msdn.microsoft.com/en-us/library/01918c6x (VS.100) .aspx). –