




libuuid(Linux/macOS)和CoCreateGuid(Windows)是生成RFC 4122标准UUID的合规方案;需正确转换格式、检查空值、初始化COM,并避免手写随机实现。
libuuid 生成标准 UUID(Linux/macOS)Linux 和 macOS 自带的 libuuid 是最轻量、最合规的选择,生成的是 RFC 4122 标准的 128-bit 随机 UUID。它不依赖 Boost 或 C++17 以上特性,编译时加 -luuid 即可。
常见错误是直接调用 uuid_generate() 后未用 uuid_unparse() 转成字符串,导致内存乱码或崩溃;还有人误把 uuid_t 当作字符串指针传给 printf。
#include
uuid_t 是 16 字节数组,不是字符串,必须用 uuid_unparse() 转换uuid_is_null() 防止生成失败(比如 /dev/urandom 不可用)uuid_t uid;
char str[37]; // 36 chars + '\0'
uuid_generate(uid);
if (!uuid_is_null(uid)) {
uuid_unparse(uid, str);
printf("UUID: %s\n", str); // e.g. "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}
CoCreateGuid() 替代Windows 没有 libuuid,但 COM 提供了系统级可靠的 CoCreateGuid(),生成的也是标准 UUID。注意必须初始化 COM 库,否则会返回 RPC_E_CHANGED_MODE 错误。
容易忽略的是:如果项目没开 COM 支持(比如纯控制台工程未调用 CoInitializeEx()),CoCreateGuid() 会静默失败,返回全零 GUID。
立即学习“C++免费学习笔记(深入)”;
#include 和 #include
CoInitializeEx(nullptr, COINIT_MULTITHREADED)
StringFromGUID2() 转字符串,输出缓冲区至少需 39 字符(含 {...} 和 \0)GUID guid;
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if (SUCCEEDED(CoCreateGuid(&guid))) {
wchar_t wstr[39];
StringFromGUID2(guid, wstr, _countof(wstr));
// 转为 UTF-8 或直接使用宽字符
}
std::random_device 手搓 UUID有人试图用 std::random_device + std::uniform_int_distribution 填充 16 字节再格式化,这**不推荐**——它生成的是伪随机字节,不满足 UUID v4 的位域规范(比如第 13 字节高 4 位必须是 0100),也不保证跨平台唯一性。
真正合规的 UUID v4 必须按 RFC 4122 设置版本号和变体位,手写易错且无必要。除非你明确知道自己在绕过系统熵源(如嵌入式无 /dev/urandom),否则别自己拼。
0100(即 0x40–0x4f),第 17 字节前 2 位固定为 10(即 0x80–0xbf)std::random_device 在某些 W
libuuid 或 Windows API,而非重实现不要写两套完全独立的生成函数,用预处理器统一入口。关键是把「生成」和「格式化」拆开,方便单元测试和替换底层实现。
容易踩的坑是把平台判断写在头文件里导致 ODR 违规,或者忘记在 Windows 下链接 ole32.lib。
std::string generate_uuid_string()
uuid_generate() + uuid_unparse()
CoCreateGuid() + StringFromGUID2(),并确保链接 ole32.lib
-DPLATFORM_WINDOWS 或自动检测 _WIN32 宏真正的难点不在生成,而在确保每次调用都访问到足够熵源、不缓存旧值、不共享 uuid_t 实例——这些细节比选哪个函数更影响可靠性。