如何将Windows GUID转换为boost::uuid?



我试图获取Windows GUID的字符串,但使用boost::uuid失败了。结果与这篇文章Boost uuid + boost endian所说的完全一样,字节顺序错误。

void foo(GUID& g)
{
boost::uuids::uuid * u = reinterpret_cast<boost::uuids::uuid*>(&g);
std::string ustr = boost::lexical_cast<std::string>(*u);
}

最后,我使用了这篇文章将 GUID 结构转换为 LPCSTR 来完成我的转换。

但我还是很好奇,

  1. 有一些优雅的方法可以将任何类型的转换为增强的
  2. 如果有,是否有现成的Windows库?
u = reinterpret_cast<boost::uuids::uuid*>(g);

我相信你应该在reinterpret_cast中取g的地址:

u = reinterpret_cast<boost::uuids::uuid*>(&g);

即使你拿了地址,我想你还有其他麻烦。Microsoft在其GUID结构中使用双字和字,而 Boost 使用字节。

Microsoft

typedef struct _GUID {
DWORD Data1;  WORD Data2;  WORD Data3;  BYTE Data4[8];
} GUID;

提升

struct uuid
{
...
public:
// or should it be array<uint8_t, 16>
uint8_t data[16];
};

我相信您需要执行以下操作进行显式转换:

void MsToBoostUuid(const GUID& ms, boost::uuids::uuid& bst)
{
bst.data[0] = static_cast<uint8_t>(ms.Data1 >> 24);
bst.data[1] = static_cast<uint8_t>(ms.Data1 >> 16);
bst.data[2] = static_cast<uint8_t>(ms.Data1 >>  8);
bst.data[3] = static_cast<uint8_t>(ms.Data1 >>  0);
bst.data[4] = static_cast<uint8_t>(ms.Data2 >> 8);
bst.data[5] = static_cast<uint8_t>(ms.Data2 >> 0);
bst.data[6] = static_cast<uint8_t>(ms.Data3 >> 8);
bst.data[7] = static_cast<uint8_t>(ms.Data3 >> 0);
bst.data[8] = ms.Data4[0];
bst.data[9] = ms.Data4[1];
...
bst.data[14] = ms.Data4[6];
bst.data[15] = ms.Data4[7];
}
void foo(const GUID& g)
{
boost::uuids::uuid u;
MsToBoostUuid(g, u);
std::string ustr = boost::lexical_cast<std::string>(*u);
}

您还可以添加运算符,例如:

inline bool operator==(const& uuid lhs, const GUID& rhs)
{
boost::uuids::uuid t;
MsToBoostUuid(rhs, t);
return std::equal(lhs.begin(), lhs.end(), t.begin());
}
inline bool operator==(const GUID& lhs, const& uuid rhs)
{
boost::uuids::uuid t;
MsToBoostUuid(lhs, t);
return std::equal(t.begin(), t.end(), rhs.begin());
}

。结果与这篇文章Boost uuid + Boost endian所说的完全一样,字节顺序错误。

我认为目前接受的答案是不正确的。我相信Dutton的回答是正确的,但它并没有向你展示UUID类型之间的典型转换。

我已经成功地使用了这段代码:

boost::uuids::uuid MakeUUID(const GUID& guid)
{
boost::uuids::uuid result;
std::memcpy(&result, reinterpret_cast<const void*>(&guid), result.size());
std::uint8_t* ch = reinterpret_cast<std::uint8_t*>(&result);
std::swap(ch[0], ch[3]);
std::swap(ch[1], ch[2]);
std::swap(ch[4], ch[5]);
std::swap(ch[6], ch[7]);
return result;
}

这与逐个字节复制相同,但是使用交换可以减少代码行数。

最新更新