【发布时间】:2013-12-09 13:27:04
【问题描述】:
我创建了一个 C++ DLL(它必须是 C++),它动态地链接一个 .Net DLL 来托管一个 Web 服务服务器。 .Net DLL 将 Web 服务调用传递给 C++ DLL,它也通过 .Net DLL 进行评估和响应。
类似的东西:
HSPWebService.DLL
-----------------------------------
HSPProxy.DLL | HSPWebServiceLib.DLL
-----------------------------------
HSPSendData.DLL
- HSPWebService.DLL - 正确的 C++ DLL。
- HSPProxy.DLL - MIDL 编译器通过 HSP.DLL MIDL 接口生成的代理。
- HSPWebServiceLib.DLL - 由 tlmbimp 通过 HSP.DLL 生成的类型库。
- HSPSendData.DLL - 托管 Web 服务服务器的 .Net DLL
一切都像一个魅力。问题是当 DLL 文件位于网络共享 (//myPc/share) 中时。我的应用程序日志显示错误 0x80131515:
CreateAssemblyInstance 错误:无法创建程序集实例。 (hr=80131515)
在我的研究中,我发现 0x80131515 错误的发生是因为 .Net 框架默认不会从外部源加载程序集。对于 .Net 项目,该选项可以设置到项目设置中。但是我在 Visual Studio 2010 上有一个 C++ 项目,我不知道在我的项目(或我的代码)上使用这个配置。有什么想法吗?
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是 deprecated。见Loading the Common Language Runtime into a Process。
标签: c++ visual-studio-2010 dll interop com-interop