【问题标题】:How to convert Windows GUID to boost::uuid?如何将 Windows GUID 转换为 boost::uuid?
【发布时间】:2019-08-26 12:59:42
【问题描述】:

我尝试获取 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);
}

最后,我使用这篇帖子Convert GUID structure to LPCSTR 完成了我的转换。

但我还是很好奇,

  1. 是否有一些优雅的方法可以将任何类型转换为 boost 的?
  2. 如果有,是否有适用于 Windows 的现成库?

【问题讨论】:

  • 根据@jww 修复的代码错字

标签: c++ boost


【解决方案1】:
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;

Boost

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 类型之间的典型转换。

【讨论】:

  • 感谢@jww 提出这个问题。我的好奇心是MsToBoost 看起来很丑。有一些优雅的转换方法吗? AND 是否有现成的库用于 Windows-to-boost 类型的隐蔽?
  • @Raymond - 我找不到:convert microsoft GUID to "boost::uuids::uuid" github。您找到的任何跨平台转换代码都将与上面的代码类似。例如,参见 Crypto++ 的 misc.h 和 Botan 的 loadstor.h。每个人都必须玩字节序游戏。
【解决方案2】:

我已成功使用此代码:

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;
}

这与逐字节复制是一样的,但使用交换可以减少代码行数。

【讨论】:

    猜你喜欢
    • 2011-03-28
    • 2020-01-20
    • 1970-01-01
    • 1970-01-01
    • 2011-04-22
    • 1970-01-01
    • 2016-08-23
    • 2014-03-28
    • 2015-06-20
    相关资源
    最近更新 更多