代码之家  ›  专栏  ›  技术社区  ›  Aurora

_com_ptr_t CreateInstance返回REGDB_E_CLASSNOTREG

  •  0
  • Aurora  · 技术社区  · 8 年前

    我有一个ATL项目,需要在其中执行各种初始化例程 CComObjectRootEx::FinalConstruct 出于演示目的,考虑以下实现:

    HRESULT FinalConstruct()
    {
        return m_bInit ? S_OK : E_FAIL;
    }
    

    这将向调用者返回适当的HRESULT,指示对象的初始化是否成功。

    然而,客户总是收到 REGDB_E_CLASSNOTREG 而不是 E_FAIL 如果失败,在尝试创建服务器时:

    #include <Windows.h>
    #import <finalconstructtest.dll>
    
    int main()
    {
        HRESULT hr = CoInitialize(0);
        {
            finalconstructtestLib::IFCClassPtr p;
    
            // Returns REGDB_E_CLASSNOTREG
            hr = p.CreateInstance(__uuidof(finalconstructtestLib::FCClass));         
        }
        CoUninitialize();
        return 0;
    }
    

    当我将类上下文更改为 CLSCTX_INPROC_SERVER 但是,将正确返回预期的HRESULT:

    // Returns E_FAIL
    hr = p.CreateInstance(__uuidof(finalconstructtestLib::FCClass), nullptr, CLSCTX_INPROC_SERVER);
    

    我看到了 this 张贴,在那里可以观察到类似的行为。然而,我似乎找不到类上下文影响 FinalConstruct 这是有意的,也许有记录在案吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Roman Ryltsov    8 年前

    CoCreateInstance API不承诺将内部故障代码转发给调用者。实现喜欢以自己的方式,通过返回 REGDB_E_CLASSNOTREG 这意味着它无法完成实例化。这反过来也是正确的:它确实无法创建实例(例如,问题与缺少接口、封送、权限等无关)。也就是说,API倾向于抑制内部故障代码,以将其替换为有文档记录的代码。

    如果您喜欢指示特定的实例化失败,那么最好先成功地创建一个实例,然后您可以实现一个具有属性或方法的接口来公开状态,或者给出相关的 HRESULT 错误(有或无 IErrorInfo 支持等)。