简体   繁体   中英

How to convert Windows GUID to boost::uuid?

I tried to get string for Windows GUID, but failed by using boost::uuid . The result is exact as this post Boost uuid + boost endian said, byte order wrong.

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

Finally, I used this post Convert GUID structure to LPCSTR to complete my convert.

But I am still curious,

  1. Is there some elegant methods to convert any types to boost's ?
  2. If there is, is there out-of-shelf libs for Windows' ?
 u = reinterpret_cast<boost::uuids::uuid*>(g); 

I believe you should take the address of g in the reinterpret_cast :

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

Even if you do take the address, I think you have other troubles. Microsoft uses double words and words in their GUID structure, while Boost uses bytes.

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

I believe you need to perform an explicit conversion with something like:

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

You can also add operators, like:

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

... the result is exact as this post Boost uuid + boost endian said, byte order wrong.

I believe the currently accepted answer is incorrect. I believe Dutton's answer is correct, but it does not show you a typical conversion between UUID types.

I've used this code with success:

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

It's the same thing as copying byte by byte, but using swap you get away with little less lines of code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM