windows - 编码 HRESULT 值:使用 FACILITY_ITF 还是设置位 29?
问题描述
如果我正在设计我自己的与 Microsoft 的 HRESULT 值共存的 COM 错误代码,我应该将设施代码设置为 FACILITY_ITF(“由返回状态代码的接口或函数的开发人员单独定义”),还是应该设置位29 表示它是客户代码?我应该两者都做吗?
如果我设置了第 29 位,我可以定义我自己的设施代码与 Microsoft 的冲突吗?
解决方案
我相信 FACILITY_ITF 可以用于您自己的界面。通常,您应该能够使用接口 ID (IID) 将您的错误与其他错误区分开来。
来自https://docs.microsoft.com/en-us/windows/desktop/com/structure-of-com-error-codes:
FACILITY_ITF 4 对于从接口方法返回的大多数状态代码。错误的实际含义由接口定义。也就是说,从两个不同接口返回的具有完全相同的 32 位值的两个 HRESULT 可能具有不同的含义。
另请参阅: https ://docs.microsoft.com/en-us/windows/desktop/com/codes-in-facility-itf (问题中已提供链接,这表明您确实可以将 FACILITY_ITF 用于您自己的界面)。
可能有一个更简单的方法,但这里有一个简单的例子:
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
// {7D51F88F-76BD-4970-BEC1-E090C032A7F5}
MIDL_DEFINE_GUID(IID, IID_MyInterface,
0x7d51f88f, 0x76bd, 0x4970, 0xbe, 0xc1, 0xe0, 0x90, 0xc0, 0x32, 0xa7, 0xf5);
// {614EBF64-44FF-4615-90DE-09D05AF7F09B}
MIDL_DEFINE_GUID(IID, IID_ISomeoneElseInterface,
0x614ebf64, 0x44ff, 0x4615, 0x90, 0xde, 0x9, 0xd0, 0x5a, 0xf7, 0xf0, 0x9b);
void TestITFFacility();
IErrorInfoPtr CreateErrorInfo(LPCTSTR desc, const CLSID& clsid, LPCWSTR source, DWORD helpContext);
int _main(int argc, TCHAR* argv[], TCHAR* envp[])
{
TestITFFacility();
return 0;
}
void TestITFFacility()
{
IID tab[2] = { IID_MyInterface, IID_ISomeoneElseInterface };
for (int i=0; i<sizeof(tab)/sizeof(IID); i++)
{
try
{
// artificially throw a _com_error.
// note: 0x0200: see https://docs.microsoft.com/en-us/windows/desktop/com/codes-in-facility-itf
// it is recommended that only code values in the range of 0x0200-0xFFFF be used
throw _com_error(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, (0x7D + 0x0200)),
CreateErrorInfo(_T("something went wrong"),
tab[i],
L"Some Source",
0));
}
catch(_com_error e)
{
auto hr = e.Error();
if (InlineIsEqualGUID(e.GUID(), IID_MyInterface))
_tprintf(_T("My Interface, hr=%08lX, code=%04X\n"), hr, e.WCode());
else
_tprintf(_T("Someone else Interface, hr=%08lX, code=%04X\n"), hr, e.WCode());
}
}
}
// method to create an IErrorInfo
IErrorInfoPtr CreateErrorInfo(LPCTSTR desc, const CLSID& clsid, LPCWSTR source, DWORD helpContext)
{
ICreateErrorInfoPtr pcerrinfo;
IErrorInfoPtr perrinfo;
HRESULT hr = CreateErrorInfo(&pcerrinfo);
assert(SUCCEEDED(hr));
if (S_OK == hr)
{
_bstr_t olestr = _bstr_t(desc);
pcerrinfo->SetDescription(olestr);
pcerrinfo->SetGUID(clsid);
pcerrinfo->SetHelpContext(helpContext);
pcerrinfo->SetSource((LPOLESTR)source);
hr = pcerrinfo->QueryInterface(IID_IErrorInfo, (LPVOID FAR*) &perrinfo);
assert(SUCCEEDED(hr));
}
return perrinfo;
}
推荐阅读
- node.js - Mongoose,无法使用 default_language 创建文本索引:'none'
- python - 电视节目上的 Last_seen 函数
- vue.js - v-model 奇怪的行为或在 VueJS 中是正常的
- python - 如何获取该表的具体文本?
- tensorflow - Windows 10 中 keras-gpu、tensorflow、cudatoolkit 和 cuDNN 之间的当前版本兼容性如何?
- sql - 使用昨天和今天的值对数据库执行操作
- reactjs - 提交时如何获取Formik initialValues?
- runtime-error - 在本地使用 SageMaker 运行超参数调整作业时出错
- react-native - 如何将文本与底部对齐?
- python - 使用 pandas 对对类别进行计数,以从一个整洁的格式 DataFrame 返回一个旋转的 DatafFame