尝试在 C++ 中加载 COM 包装的 DLL 时出现未处理的异常
Unhandled exception when trying to load a COM wrapped DLL in C++
我在 .NET
中有一个程序集,我已经通过 COM
公开了该程序集并命名为强名称。
部署后,此程序集需要出现在 GAC
中。但是,我需要在创建对象之前检查它是否存在。
不幸的是,如果 GAC 中不存在程序集,即使将对象创建放在 try / catch 中也会在运行时导致 unhandled exception
。
所以在我继续创建对象之前,我必须有一些方法来验证 DLL 是否确实安装在 GAC 中。
HINSTANCE histLib;
histLib = LoadLibrary("CLSInterOpLibrary.dll");
if (histLib == NULL)
return false;
encode();
CoInitialize(NULL);
try
{
CLSInterOpLibrary::CLSInterOpInterfacePtr p(__uuidof(CLSInterOpLibrary::CLSInterOpClass));
if (p == nullptr)
return false;
com_ptr = p;
}
catch (exception &e)
{
}
LoadLibrary
给出 NULL,无论该库是否存在于 GAC 中,可能需要某种路径...,并且
CLSInterOpLibrary::CLSInterOpInterfacePtr p(__uuidof(CLSInterOpLibrary::CLSInterOpClass));
..如果 DLL 不存在则给出未处理的异常。
那么如何检查 DLL
是否安装在 GAC
和 C++?
或者是否有更优雅的解决方案?
不要 调用 LoadLibrary(),这会起作用的可能性非常小,尤其是当程序集实际安装在 GAC 中时。查找 DLL 是 COM 的工作,它使用注册程序集时写入的注册表项。
您需要修复错误处理,您从#import 指令获得的 CLSInterOpInterfacePtr 智能指针类型将 HRESULT 错误代码转换为异常。您需要 try/catch 才能赶上 _com_error exception。试图抓住 std::exception 是行不通的,_com_error 不是从它派生的。
这足以诊断注册问题或缺少 DLL。如果未注册 COM 服务器,您获得的样板 _com_error::Error 值为 REGDB_E_CLASSNOTREG (0x80040154),"Class not registered",如果 CLR 在定位 DLL 时遇到问题,则更具体一些。 _com_error::Description() 方法为您提供了一条可以显示或记录的合理消息。神圣的堆栈跟踪遥不可及。
我在 .NET
中有一个程序集,我已经通过 COM
公开了该程序集并命名为强名称。
部署后,此程序集需要出现在 GAC
中。但是,我需要在创建对象之前检查它是否存在。
不幸的是,如果 GAC 中不存在程序集,即使将对象创建放在 try / catch 中也会在运行时导致 unhandled exception
。
所以在我继续创建对象之前,我必须有一些方法来验证 DLL 是否确实安装在 GAC 中。
HINSTANCE histLib;
histLib = LoadLibrary("CLSInterOpLibrary.dll");
if (histLib == NULL)
return false;
encode();
CoInitialize(NULL);
try
{
CLSInterOpLibrary::CLSInterOpInterfacePtr p(__uuidof(CLSInterOpLibrary::CLSInterOpClass));
if (p == nullptr)
return false;
com_ptr = p;
}
catch (exception &e)
{
}
LoadLibrary
给出 NULL,无论该库是否存在于 GAC 中,可能需要某种路径...,并且
CLSInterOpLibrary::CLSInterOpInterfacePtr p(__uuidof(CLSInterOpLibrary::CLSInterOpClass));
..如果 DLL 不存在则给出未处理的异常。
那么如何检查 DLL
是否安装在 GAC
和 C++?
或者是否有更优雅的解决方案?
不要 调用 LoadLibrary(),这会起作用的可能性非常小,尤其是当程序集实际安装在 GAC 中时。查找 DLL 是 COM 的工作,它使用注册程序集时写入的注册表项。
您需要修复错误处理,您从#import 指令获得的 CLSInterOpInterfacePtr 智能指针类型将 HRESULT 错误代码转换为异常。您需要 try/catch 才能赶上 _com_error exception。试图抓住 std::exception 是行不通的,_com_error 不是从它派生的。
这足以诊断注册问题或缺少 DLL。如果未注册 COM 服务器,您获得的样板 _com_error::Error 值为 REGDB_E_CLASSNOTREG (0x80040154),"Class not registered",如果 CLR 在定位 DLL 时遇到问题,则更具体一些。 _com_error::Description() 方法为您提供了一条可以显示或记录的合理消息。神圣的堆栈跟踪遥不可及。