C+中的GUID常量+;(在特定的奥威尔开发-C+;+;) < >我把很多插件从Delphi翻译成C++,每个插件都用GUID识别。
在Delphi中,这个常量看起来非常好:C+中的GUID常量+;(在特定的奥威尔开发-C+;+;) < >我把很多插件从Delphi翻译成C++,每个插件都用GUID识别。,c++,guid,C++,Guid,在Delphi中,这个常量看起来非常好: const GUID_PLUGIN_ABC_V1: TGUID = '{6C26245E-F79A-416C-8C73-BEA3EC18BB6E}'; P>在我的C++翻译中,我需要做如下: static const GUID GUID_PLUGIN_ABC_V1 = {0x6C26245E, 0xF79A, 0x416C, { 0x8C, 0x73, 0xBE, 0xA3, 0xEC, 0x18, 0xBB, 0x6E} }; 这很烦人,
const
GUID_PLUGIN_ABC_V1: TGUID = '{6C26245E-F79A-416C-8C73-BEA3EC18BB6E}';
<> P>在我的C++翻译中,我需要做如下:
static const GUID GUID_PLUGIN_ABC_V1 =
{0x6C26245E, 0xF79A, 0x416C, { 0x8C, 0x73, 0xBE, 0xA3, 0xEC, 0x18, 0xBB, 0x6E} };
这很烦人,因为有两件事:
// {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";
}
#包括
编辑:解析
#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';
}
#包括
#包括
#包括
#包括
#包括
#pragma包(推送,0)
结构Guid
{
标准:uint32_t数据1;
标准:uint16_t数据2;
标准:uint16_t数据3;
std::数组数据4;
};
#布拉格语包(流行语)
//格式为“01234567-89ab-cdef-0123-456789abcdef”的guid
//如果guid字符串无效,则生成的guid为空guid。
//注意:guid的前三个字段以主机字节顺序存储。
//最后两个字段存储在一个数组中(big-endian)
Guid运算符“”\u Guid(常量字符*s,标准::大小\u t n)
{
//十六进制字符测试。
结构IsXDigit
{
布尔结果=真;
IsXDigit(常量字符*&p,无符号n)
{
而(n--){
字符c=*p++;
//字符可以是有符号的,也可以是无符号的
如果(c<0 | | 128因为您只是以不同的格式从一个文本转换到另一个文本,那么Regex find and replace将非常适用于此。以下是在Notepad++中开发和测试的。不同的编辑器(如Visual Studio)可能有不同的Regex规则,但基本原理是相同的
搜索:
const ([\w]+)\: TGUID = '\{(.{8})-(.{4})-(.{4})-(..)(..)-(..)(..)(..)(..)(..)(..)\}';
替换为:
static const GUID $1 = {0x$2, 0x$3, 0x$4, { 0x$5, 0x$6, 0x$7, 0x$8, 0x$9, 0x$10, 0x$11, 0x$12} };
我无法解释使用正则表达式搜索的所有细节,但需要了解的基本情况是,搜索字符串“capture”中的括号是行的匹配区域,在替换字符串$1、$2等中插入捕获的内容
例如,第一组括号是([\w]+)
。它用于捕获GUID的名称(GUID\u PLUGIN\u ABC\u V1
)。要分解它,[\w]
表示“匹配所有单词字符”,而+
表示“匹配一个或多个前面的字符”。括号捕获它,$1将名称添加到替换字符串中。({8})
组是“匹配任意字符8次”,而(…)
是猪鼻子…但是说真的,
表示“任意字符”,所以(…)
只匹配两个字符
请注意,此regex find and replace选项假定所有传入的GUID字符串都有效,并遵循以下格式:
const <GUID NAME>: TGUID = '{<GUID STRING>}';
const:TGUID='{}';
如果有任何变化,对正则表达式的轻微更改可以解释这些变化。最糟糕的情况是,您有一些不同的搜索和替换字符串,基于您的各种GUID格式。看看这篇SO帖子,它似乎有您要找的答案:@DavidHaim这条评论绝对没有必要,也没有帮助。在VC++中问题也一样。关于Dev-C++:它是一个很好的工具,适用于小项目,尤其是插件,它们只有一个小的DLL文件。与VC++相比,Dev-C++总是开箱即用地运行和编译(感谢MinGW GCC编译器)。@YePhIcK,尽管这个函数在我的计算机(Win10)上工作微软声明这是针对CLSID的,但是我的GUID与COM无关,因此没有注册。该方法可能会失败。这将有助于GUIDFromString的功能,但微软出于某些原因表示不赞成。将Delphi格式转换成新的C++格式的代码可以用基本的,尽管长的正则表达式实现。关于查找和替换。让我看看是否可以创建它并作为答案发布。我不太了解运算符\u guid
的作用。我要转换的guid已经用此方法写入。因此guid在代码中是3倍,2倍为字符串,1倍为拆分结构(我希望避免)。因此,此方法转换已转换为硬编码的内容?此代码允许您复制和粘贴Delphi GUI,但您必须将其替换为“和append _GUID实际的问题是我不想手动编写像result.a=0x6C26245E;
这样的东西。@如果您必须解析字符串,我忽略了在上面的示例中,我试图将您的函数用于实际的数据类型GUID(在WinAPI的guiddef.h中定义),其定义如下:。因此,我将签名更改为GUID operator”“\u GUID(const char*s,std::size\t n)
,但我得到的编译器错误[error]与“operator=”不匹配(操作数类型为“GUID{aka_GUID}”和“const char[39]”