我有一个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
的返回值的任何理由。这是有意的,也许是在某处记录的吗?
答案 0 :(得分:1)
CoCreateInstance
API不承诺将内部失败代码转发给调用者。实现更喜欢以自己的方式指示问题的根源,方法是返回REGDB_E_CLASSNOTREG
,意味着它无法完成实例化。反过来也是如此:它确实无法创建实例(例如,问题不在于缺少接口,封送,权限等)。也就是说,API倾向于禁止内部故障代码,以用记录的代码替换它。
如果您希望指出特定的实例化失败,那么最好在初始创建实例时成功,然后您可以实现具有属性或方法的接口,从而暴露状态或提供相关的HRESULT
错误(有或没有IErrorInfo
支持等。)