问题 如何初始化常量CLSID


类ID(GUID)通常用由破折号分隔的十六进制数字序列指定,例如, {557cf406-1a04-11d3-9a73-0000f81ef32e}。这不是可用于直接初始化CLSID结构的文字。

我发现了两种初始化结构的方法,但它们都很尴尬。第一个不允许声明它 const 并且必须在运行时完成,而第二个需要对十六进制常量进行大量重新格式化。

CLSID clsid1;
CLSIDFromString(CComBSTR("{557cf406-1a04-11d3-9a73-0000f81ef32e}"), &clsid1);

const CLSID clsid2 = { 0x557cf406, 0x1a04, 0x11d3, { 0x9a,0x73,0x00,0x00,0xf8,0x1e,0xf3,0x2e } };

我知道如果你有一个与UUID相关联的类型,Visual Studio可以自动生成一个 __uuidof 操作者。如果你只有十六进制字符串,有没有办法做到这一点?


6946
2018-04-30 19:14


起源

咳咳: stackoverflow.com/questions/5345803/... - i_am_jorf
您始终可以使用调用的工厂函数 CLSIDFromString - 就像是 const CLSID clsid1 = GUIDFactoryFunc("{557cf406-1a04-11d3-9a73-0000f81ef32e}") - Captain Obvlious
@i_am_jorf为什么你认为我在问这个问题?我需要在一个新程序中使用该问题的答案,而我之前写的代码是一个工作之前,不再可供参考。 - Mark Ransom


答案:


静态的 CLSID 从字符串初始化(不需要运行时转换助手):

class __declspec(uuid("{557cf406-1a04-11d3-9a73-0000f81ef32e}")) Foo;
static const CLSID CLSID_Foo = __uuidof(Foo);       
// ...
CComPtr<IUnknown> pUnknown;
pUnknown.CoCreateInstance(CLSID_Foo);

或者直接使用 __uuidof (编译器会将GUID值视为常量并生成最少的必要代码):

class __declspec(uuid("{557cf406-1a04-11d3-9a73-0000f81ef32e}")) Foo;
// ...
CComPtr<IUnknown> pUnknown;
pUnknown.CoCreateInstance(__uuidof(Foo));

它没有什么特别之处:例如,当类型库是 #imported,使用相同的方法进行附加 CLSIDs到基于coclass的类型,然后是附加的 CLSID_xxx 如果,则可能生成标识符 还要求


8
2018-05-01 06:26



一个好的。也可以使用一些宏来使它成为一个单行。 - Noseratio
实际上没有必要定义 CLSID_Foo 因为 __uuidof(Foo) 可以直接使用(使它已经是单行)。 - Roman R.
我认为OP想要一个 const CLSID所以我提到了宏。 - Noseratio


使用辅助函数来创建GUID。

#include <Windows.h>
#include <atlbase.h>

template<class S>
CLSID CreateGUID(const S& hexString)
{
    CLSID clsid;
    CLSIDFromString(CComBSTR(hexString), &clsid);

    return clsid;
}

int main()
{
    const CLSID clsid1 = CreateGUID("{557cf406-1a04-11d3-9a73-0000f81ef32e}");
    const CLSID clsid2 = CreateGUID(L"{557cf406-1a04-11d3-9a73-0000f81ef32e}");
}

2
2018-04-30 19:42