尝试在 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 是否安装在 GACC++? 或者是否有更优雅的解决方案?

不要 调用 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() 方法为您提供了一条可以显示或记录的合理消息。神圣的堆栈跟踪遥不可及。