C++ 是否有操作系统功能将refid转换为有用的名称?

C++ 是否有操作系统功能将refid转换为有用的名称?,c++,windows,com,windows-shell,C++,Windows,Com,Windows Shell,不需要手动编写函数,将一些已知的refid转换为名称,例如: if (riid == IID_IUnknown) return "IUnknown"; if (riid == IID_IShellBrowser) return "IShellBrowser"; ... 是否有一个系统调用会为已知(甚至所有)refiID返回合理的调试字符串?您可以在HKCR\Interface registry子树中查找预定义接口。如果愿意,任何组件都可以在那里注册其接口。但是这不是强制性的-组件可能会跳过此注

不需要手动编写函数,将一些已知的refid转换为名称,例如:

if (riid == IID_IUnknown) return "IUnknown";
if (riid == IID_IShellBrowser) return "IShellBrowser";
...

是否有一个系统调用会为已知(甚至所有)refiID返回合理的调试字符串?

您可以在HKCR\Interface registry子树中查找预定义接口。如果愿意,任何组件都可以在那里注册其接口。但是这不是强制性的-组件可能会跳过此注册。

感谢您的回复。以下是我根据您的反馈提出的建议-非常感谢

CString ToString(const GUID & guid)
{
    // could use StringFromIID() - but that requires managing an OLE string
    CString str;
    str.Format(_T("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"),
        guid.Data1,
        guid.Data2,
        guid.Data3,
        guid.Data4[0],
        guid.Data4[1],
        guid.Data4[2],
        guid.Data4[3],
        guid.Data4[4],
        guid.Data4[5],
        guid.Data4[6],
        guid.Data4[7]);
    return str;
}

CString GetNameOf(REFIID riid)
{
    CString name(ToString(riid));
    try
    {
        // attempt to lookup the interface name from the registry
        RegistryKey::OpenKey(HKEY_CLASSES_ROOT, "Interface", KEY_READ).OpenSubKey("{"+name+"}", KEY_READ).GetDefaultValue(name);
    }
    catch (...)
    {
        // use simple string representation if no registry entry found
    }
    return name;
}

永远不要使用
catch(…)
。这有许多不同的哲学原因,但如果您想有一个实用的原因:要通过“专为Vista设计”验证,您的应用程序需要永远不要捕获访问冲突异常。根据您的编译器设置,
catch(…)
会执行此操作。此外,要在MFC或ATL应用程序中管理OLE字符串(即BSTR),请使用
CComBSTR
类。没有任何理由调用OLE字符串的所有开销。是的,这是有机制的,但那又怎样呢?他们不能只是去改变他们表达guid的方式,所以这不是一个移动的目标,所以不需要冒险推出我自己的、更有效的解决方案。我同意你关于catch(…)问题的一般经验法则——在代码中随意使用catch(…)并不是一个好主意。但我想说,它肯定有自己的位置。以一个类的析构函数为例,该类通过其他对象管理OS文件,如果与底层文件交互时出现IO错误,该对象将引发。。。如果需要从类的dtor中调用这样的函数,那么一种合理的方法是将所述调用封装在try{}catch(…)中。否则,您基本上可以保证您的应用程序将使用CTD。您可以使用StringFromGUID2()-它将愉快地接受堆栈分配的缓冲区,而不需要OLE字符串。