- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在将很多插件从 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} };
这很烦人,因为有两件事:
我很难翻译,因为我需要手动拆分我的 GUID,并且存在出错的风险(因此提供了错误的 GUID)。
由于来源是公开的,我确实希望人们使用人类可读的 GUID,例如将其用于网络研究等。所以我需要在常量上方添加注释:
// {6C26245E-F79A-416C-8C73-BEA3EC18BB6E}
static const GUID GUID_PLUGIN_ABC_V1 =
{0x6C26245E, 0xF79A, 0x416C, { 0x8C, 0x73, 0xBE, 0xA3, 0xEC, 0x18, 0xBB, 0x6E} };
现在我有以下问题:
有没有可能我可以使用宏,比如
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/
在 Dev-C++ 中,当我用 编译我的程序时 LPCTSTR ClsName = L"BasicApp"; LPCTSTR WndName = L"A Simple Window"; 编译中断,但是
这个问题在这里已经有了答案: Default constructor with empty brackets (9 个回答) 关闭 8 年前。 我最近写了下面的简单程序,但编译器显示警告。 #inc
我正在尝试使用 Orwell Dev C++ 中的任何 C++11 功能,但没有成功。我安装了带有 minGW 的版本以及我在编译器选项中设置的任何内容,我只是在这段代码中得到“[Error] 'to
我正在尝试用 Orwell Dev-C++ 编译在另一台机器上编写的头文件。我刚刚下载了 Dev-C++,所以我对它不是很熟悉。以下是导致问题的代码片段: #ifndef JOB_H #define
尝试编译以下代码: #include #include struct Foo { Foo() { std::cout p1(new Foo); // p1 owns Foo i
我是这方面的新手,昨天我安装了 Win 8.1 x64,所以我想使用最合适的程序在 C/C++ 中完成我的任务。谢谢 最佳答案 MinGW 仅支持32 位 二进制文件,TDM 支持 32 和 64 位
我正在将很多插件从 Delphi 翻译成 C++,每个插件都由一个 GUID 标识。 在 Delphi 中,这个常量看起来很不错: const GUID_PLUGIN_ABC_V1: TGUID
我是一名优秀的程序员,十分优秀!