gpt4 book ai didi

c++ - C++ 中的 GUID 常量(在特定的 Orwell Dev-C++ 中)

转载 作者:行者123 更新时间:2023-11-30 02:36:27 24 4
gpt4 key购买 nike

我正在将很多插件从 Delphi 翻译成 C++,每个插件都由一个 GUID 标识。

在 Delphi 中,这个常量看起来很不错:

const
GUID_PLUGIN_ABC_V1: TGUID = '{6C26245E-F79A-416C-8C73-BEA3EC18BB6E}';

在我的 C++ 翻译中,我需要执行以下操作:

static const GUID GUID_PLUGIN_ABC_V1 =
{0x6C26245E, 0xF79A, 0x416C, { 0x8C, 0x73, 0xBE, 0xA3, 0xEC, 0x18, 0xBB, 0x6E} };

这很烦人,因为有两件事:

  1. 我很难翻译,因为我需要手动拆分我的 GUID,并且存在出错的风险(因此提供了错误的 GUID)。

  2. 由于来源是公开的,我确实希望人们使用人类可读的 GUID,例如将其用于网络研究等。所以我需要在常量上方添加注释:

    // {6C26245E-F79A-416C-8C73-BEA3EC18BB6E}
    static const GUID GUID_PLUGIN_ABC_V1 =
    {0x6C26245E, 0xF79A, 0x416C, { 0x8C, 0x73, 0xBE, 0xA3, 0xEC, 0x18, 0xBB, 0x6E} };

现在我有以下问题:

  1. 是否有适合此任务(针对现有 GUID)的转换器
  2. 是否有一种工具可以用这种常量表示法创建新的 GUID?
  3. 有没有可能我可以使用宏,比如

    static const GUID GUID_PLUGIN_ABC_V1 =
    GUIDMACRO('{6C26245E-F79A-416C-8C73-BEA3EC18BB6E}')

    ?

GUID 与 COM 无关。

最佳答案

您可以使用用户定义的文字:

#include <array>
#include <cstring>
#include <iostream>

struct Guid
{
uint32_t a = 0;
uint16_t b = 0;
uint16_t c = 0;
uint16_t d = 0;
std::array<uint8_t, 6> e;
};

Guid operator "" _guid (const char* s, std::size_t n)
{
if(n == 38)
{
// Parse and consider byte order (endian).
// Provide something reasonable to replace this:
if(std::strncmp(s, "{6C26245E-F79A-416C-8C73-BEA3EC18BB6E}", 36) == 0)
{
Guid result;
result.a = 0x6C26245E;
result.b = 0xF79A;
result.c = 0x416C;
result.d = 0x8C73;
result.e = { 0xBE, 0xA3, 0xEC, 0x18, 0xBB, 0x6E };
return result;
}
}
// Invalid
return Guid();
}

int main()
{
Guid guid = "{6C26245E-F79A-416C-8C73-BEA3EC18BB6E}"_guid;
std::cout << std::hex
<< guid.a << "-"
<< guid.b << "-"
<< guid.c << "-"
<< guid.d << "-"
<< "array\n";
}

参见 http://en.cppreference.com/w/cpp/language/user_literal

编辑:解析

#include <array>
#include <cctype>
#include <cstdint>
#include <cstdlib>
#include <cstring>

#pragma pack(push, 0)
struct Guid
{
std::uint32_t data1;
std::uint16_t data2;
std::uint16_t data3;
std::array<uint8_t, 8> data4;
};
#pragma pack(pop)

// A guid with the format "01234567-89ab-cdef-0123-456789abcdef"
// If the guid string is invalid the resulting guid is an empty guid.
// Note: The first three fields of the guid are stored in a host byte order.
// and the last two fields are stored in a single array (big endian)
Guid operator "" _guid (const char* s, std::size_t n)
{
// Hexadecimal character test.
struct IsXDigit
{
bool result = true;
IsXDigit(const char*& p, unsigned n)
{
while(n--) {
char c = *p++;
// char may be signed or unsigned
if(c < 0 || 128 <= c || ! std::isxdigit(c)) {
result = false;
break;
}
}
}
operator bool () const { return result; }
};

Guid result;

// Syntax
const char* p = s;
if( ! IsXDigit(p, 8)) goto Failure;
if(*p++ != '-') goto Failure;
if( ! IsXDigit(p, 4)) goto Failure;
if(*p++ != '-') goto Failure;
if( ! IsXDigit(p, 4)) goto Failure;
if(*p++ != '-') goto Failure;
if( ! IsXDigit(p, 4)) goto Failure;
if(*p++ != '-') goto Failure;
if( ! IsXDigit(p, 12)) goto Failure;
if(*p) goto Failure;

// Data
result.data1 = std::uint32_t(std::strtoul(s, nullptr, 16));
result.data2 = std::uint16_t(std::strtoul(s + 9, nullptr, 16));
result.data3 = std::uint16_t(std::strtoul(s + 14, nullptr, 16));
char buffer[3];
buffer[2] = 0;
for(unsigned dst = 0, src = 19; src < 23; ++dst, src += 2)
{
buffer[0] = s[src];
buffer[1] = s[src + 1];
result.data4[dst] = std::uint8_t(std::strtoul(buffer, nullptr, 16));
}
for(unsigned dst = 2, src = 24; src < 36; ++dst, src += 2)
{
buffer[0] = s[src];
buffer[1] = s[src + 1];
result.data4[dst] = std::uint8_t(std::strtoul(buffer, nullptr, 16));
}
return result;

Failure:
std::memset(&result, 0, sizeof(result));
return result;
}


#include <iostream>
#include <iomanip>

int main()
{
const Guid guid = "6C26245E-F79A-416C-8C73-BEA3EC18BB6E"_guid;
std::cout.fill('0');
std::cout
<< std::hex
<< "6C26245E-F79A-416C-8C73-BEA3EC18BB6E\n"
<< std::setw(8) << guid.data1 << "-"
<< std::setw(4) << guid.data2 << "-"
<< std::setw(4) << guid.data3 << "-";
for(unsigned i = 0; i < 2; ++i)
std::cout << std::setw(2) << unsigned(guid.data4[i]);
std::cout << "-";
for(unsigned i = 2; i < 8; ++i)
std::cout << std::setw(2) << unsigned(guid.data4[i]);
std::cout << '\n';
}

关于c++ - C++ 中的 GUID 常量(在特定的 Orwell Dev-C++ 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32745372/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com