【问题标题】:_com_ptr_t CreateInstance returns REGDB_E_CLASSNOTREG_com_ptr_t CreateInstance 返回 REGDB_E_CLASSNOTREG
【发布时间】:2016-09-29 11:47:00
【问题描述】:

我有一个 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 的返回值。这是否有意并可能记录在某处?

【问题讨论】:

    标签: c++ com atl


    【解决方案1】:

    CoCreateInstance API 不承诺将内部故障代码转发给调用者。实现更喜欢以自己的方式指出问题的根源,通过返回REGDB_E_CLASSNOTREG 表示它无法完成实例化。这反过来又是正确的:它确实无法创建实例(例如,问题与缺少接口、编组、权限等无关)。也就是说,API 更喜欢隐藏内部故障代码,以用记录在案的代码替换它。

    如果你更愿意指出一个特定的实例化失败,你最好先成功创建一个实例,然后你可以实现一个带有属性或方法暴露状态的接口,或者给出相关的HRESULT错误(带有或没有IErrorInfo 支持等)。

    【讨论】:

      猜你喜欢
      • 2013-02-28
      • 1970-01-01
      • 2020-12-28
      • 1970-01-01
      • 2011-10-16
      • 2015-07-15
      • 1970-01-01
      • 1970-01-01
      • 2011-03-01
      相关资源
      最近更新 更多