当前位置: 首页 > news >正文

厦门市住房和建设局网站在线图片编辑工具

厦门市住房和建设局网站,在线图片编辑工具,做网站维护需要懂什么,百度网页推广类型的 GUID#xff08;全局唯一标识符#xff09; 是在 COM 编程#xff08;Component Object Model#xff09; 和某些大型 C 架构#xff08;如 Office、DirectX、跨 DLL 接口#xff09;中关联类型信息和实现运行时类型识别与动态接口查询的重要机制。 下面我们分层解…类型的 GUID全局唯一标识符 是在 COM 编程Component Object Model 和某些大型 C 架构如 Office、DirectX、跨 DLL 接口中关联类型信息和实现运行时类型识别与动态接口查询的重要机制。 下面我们分层解释—— 类型的 GUID 是什么 GUIDGlobally Unique Identifier128 位的唯一标识用来唯一标识某种类型接口/类。 比如 __declspec(uuid(4D675322-F6F5-4E85-94EF-2927DFAA1409)) struct IWorkerCallback : IUnknown { ... };这个 GUID 表示IWorkerCallback 类型的唯一身份标识是这个字符串值。 GUID 的用途为什么类型需要它 1. COM 接口查询核心用途 COM 是基于接口的架构组件之间只能通过接口通信。你不能像 C 的 dynamic_cast 那样直接转换接口指针所以需要 HRESULT QueryInterface(const IID iid, void** out);你必须提供要“转换到的接口”的 IID也就是接口的 GUID比如 pUnknown-QueryInterface(__uuidof(IMyInterface), (void**)pMyInterface);这背后的意思是我想知道你是否实现了 IMyInterface请给我这个接口指针如果有的话。 2. 替代 RTTI无需开启 -frtti 有些大型项目如 Office**禁用了 RTTI运行时类型信息**以节省空间。通过 GUID我们就能在运行时识别类型、接口并动态转换而不用启用 C 的原生 typeid 或 dynamic_cast。 3. 跨 DLL 类型识别 在 Windows DLL 边界上类型信息是不能直接共享的但 GUID 可以。于是 DLL A 定义了 IFoo。DLL B 想和它通信只要知道 IFoo 的 GUID 就行了无需包含 IFoo 的完整实现。 4. 插件机制和反射支持 如果你要构建 跨平台插件框架脚本调用如 Lua → C元数据反射识别支持的功能 你也可以使用类型 GUID 来注册所有类型用 GUID 映射构造函数、工厂函数、接口表甚至用于序列化/反序列化type-safe 不是 C 标准的机制 GUID 和 __uuidof() 不是 C 标准提供的功能而是 Microsoft Visual C 提供的扩展__declspec(uuid)Clang/GCC 等可以通过宏和模板模拟如你前面看到的 STRUCT_GUID 举个实际例子 IUnknown* p ...; IFoo* foo nullptr; if (SUCCEEDED(p-QueryInterface(__uuidof(IFoo), (void**)foo))) {foo-DoSomething(); }没有 GUID你就无法调用 QueryInterface()类型系统没法知道“你到底想要哪个接口”。 总结一句话 类型的 GUID 是类型在运行时的身份证它是 COM 等架构中实现接口查询QueryInterface、替代 RTTI、支持插件与 DLL 通信的核心机制。 总结一下为什么需要类型的 GUID GUID全局唯一标识符用于标识接口类型特别是在 COM组件对象模型编程中比如 Microsoft Office 里的代码。通过 IUnknown::QueryInterface 方法可以根据 GUID 实现接口的动态查询和类型转换类似于动态类型转换但不依赖于 C 的 RTTI。Office 里不使用 C 标准的 RTTI而是用 GUID 来保证跨模块、跨语言的一致性和安全性。Visual C 提供了对 GUID 的内置支持通过 __declspec(uuid(...)) 来声明 GUID通过 __uuidof(Type) 获取类型对应的 GUID。C 标准并没有内建对 GUID 的支持所以这是 Microsoft 平台特有的扩展。 这段代码展示了一个跨平台特别是支持 MSVC 和 Clang 编译器对 GUID 与接口类型关联的典型写法核心点如下 __declspec(uuid(...)) 是 MSVC 特有的语法用于给接口如 IWorkerCallback附加 GUID。在 MSVC 下__uuidof(type) 可以直接获取这个 GUID。Clang 编译器不支持 __declspec(uuid) 的模板特化所以采用模板特化结构体 guid_oftype 来手动绑定 GUID。通过宏 #define __uuidof(type) guid_oftype::value无论在哪个编译器环境都能统一用 __uuidof(type) 方式获取 GUID。这样写能实现跨编译器一致访问 GUID同时保证代码跨平台兼容。 总结一下这个理想方案的问题点 [uuid(“…”)] 标注虽然写起来直观简洁但它是 微软专有扩展不属于标准 C只能在 Visual C 使用其实现会在对象实例中增加额外指针导致对象体积变大这对性能敏感或跨平台项目是不友好的。 所以虽然它“看上去理想”但实际用时要慎重最好还是用兼容性更好、对实例大小无影响的传统 __declspec(uuid(...)) 模板特化方案。 总结一下这个用宏简化 GUID 绑定的关键点 宏写成 STRUCT_GUID(IWorkerCallback, 4D675322-F6F5-4E85-94EF-2927DFAA1409) 形式 宏只负责绑定 GUID不包含 struct 或 class 关键字 这样更利于 IDE 和工具解析代码语法高亮、跳转等。struct 或 class 关键字放在宏外写方便代码风格统一和工具支持。注意宏绑定的 GUID 必须和类型的声明匹配比如不能宏里用 class类型定义里用 struct否则会产生 Visual C 的 Level 1 警告。保证这点对 Visual C 的 ABI 稳定性很重要避免潜在兼容性问题。 How can we implement the STRUCT_GUID macro? 这段代码意思是 #define STRUCT_GUID(type, guidString) \struct __declspec(uuid(guidString)) type;这个宏利用 Visual C 的 __declspec(uuid(...)) 特性直接把 GUID 绑定到 struct 上。宏只负责给类型添加 GUID 属性不管是定义、前置声明还是重新声明都可以使用这个宏。实现非常简单明了使用方便。 比如 STRUCT_GUID(IWorkerCallback, 4D675322-F6F5-4E85-94EF-2927DFAA1409) struct IWorkerCallback : IUnknown {virtual void Invoke(IWorkerObject* pObj) 0; };这样IWorkerCallback 类型就绑定了对应的 GUIDVC 编译器会自动生成相关信息。 这段描述是 Clang 下跨平台实现 GUID 关联的思路主要点如下 核心思想 不像 VC 直接用 __declspec(uuid(...))Clang 没有类似的内建支持需要用模板和函数来“模拟” GUID 关联。定义一个模板结构体 guid_ofT它有一个 static constexpr GUID value存储对应类型的 GUID。__uuidof(type) 宏映射到 guid_oftype::value这样用起来语义一致。 关键实现细节 // 默认模板调用 get_guid 函数 templatetypename T struct guid_of {static constexpr GUID value get_guid(static_castT*(nullptr)); }; // 默认 get_guid 函数实现static_assert 防止未特化情况导致使用错误 templatetypename T constexpr GUID get_guid(T*) {static_assert(sizeof(T) 0, GUID not defined for this type!); } // 用宏定义类型的 GUID宏展开成 get_guid 函数的特化版本 #define STRUCT_GUID(type, guidString) \struct type; \extern C constexpr GUID get_guid(type*) noexcept { \return str_to_guid(guidString); \}STRUCT_GUID(type, guidString) 会先声明一个 struct type再定义一个针对该类型指针的 get_guid 函数特化返回对应的 GUID。通过 str_to_guid 将字符串形式的 GUID 转换为 GUID 结构。当你调用 __uuidof(type) 时实际是访问 guid_oftype::value编译器会调用对应的 get_guid(type*)返回正确的 GUID。如果没有使用 STRUCT_GUID 定义的类型调用 __uuidof 会触发 static_assert提示没有定义 GUID。 优点 支持 Clang 以及非 VC 编译器。类型安全调用时若未定义 GUID 会报错。不改变结构体大小或内存布局。 你提供的这段代码是对 Clang 下如何在 C 中实现编译期 GUID全局唯一标识符解析 的继续部分。下面是对这段实现的完整讲解 /// 表示一个不带花括号的 GUID 字符串格式为 XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX typedef char GuidString[37]; /// 把十六进制的 ASCII 字符转换为无符号整数值0–15 /// H2U[0] 0, H2U[9] 9, H2U[A] 10, H2U[F] 15, H2U[a] 10, H2U[f] 15 const unsigned char H2U[256] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /// 将格式为 XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 的字符串在编译期转换为 GUID 结构 constexpr GUID str_to_guid(const GuidString g) noexcept {return {// 第1段8位十六进制→ unsigned longstatic_castunsigned long((H2U[g[0]] 28) | (H2U[g[1]] 24) | (H2U[g[2]] 20) |(H2U[g[3]] 16) | (H2U[g[4]] 12) | (H2U[g[5]] 8) |(H2U[g[6]] 4) | H2U[g[7]]),// 第2段4位十六进制→ unsigned shortstatic_castunsigned short((H2U[g[9]] 12) | (H2U[g[10]] 8) |(H2U[g[11]] 4) | H2U[g[12]]),// 第3段4位十六进制→ unsigned shortstatic_castunsigned short((H2U[g[14]] 12) | (H2U[g[15]] 8) |(H2U[g[16]] 4) | H2U[g[17]]),// 第4和第5段4位 12位十六进制→ 8字节 unsigned char[8]{static_castunsigned char((H2U[g[19]] 4) | H2U[g[20]]),static_castunsigned char((H2U[g[21]] 4) | H2U[g[22]]),static_castunsigned char((H2U[g[24]] 4) | H2U[g[25]]),static_castunsigned char((H2U[g[26]] 4) | H2U[g[27]]),static_castunsigned char((H2U[g[28]] 4) | H2U[g[29]]),static_castunsigned char((H2U[g[30]] 4) | H2U[g[31]]),static_castunsigned char((H2U[g[32]] 4) | H2U[g[33]]),static_castunsigned char((H2U[g[34]] 4) | H2U[g[35]])}}; }目的 Clang 不支持 __declspec(uuid(...))所以我们自己构建一种方式在 编译期将字符串形式的 GUID 解析为结构体形式即 GUID{...}以便类型绑定使用。 关键元素解释 1. GuidString 类型定义 typedef char GuidString[37];用于表示标准 GUID 格式的字符串 XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX共 36 个字符 终止符。格式示例4D675322-F6F5-4E85-94EF-2927DFAA1409 2. H2U 十六进制字符转换表 const unsigned char H2U[256] { ... };将 0–9、A–F、a–f 转换为 0–15。例如H2U[A] 10H2U[f] 15其它值都默认为 0避免非 hex 字符崩溃。 3. str_to_guid将字符串转为 GUID constexpr GUID str_to_guid(const GuidString g) noexcept工作流程按 GUID 各字段分段解释 // DWORD Data1 8 hex digits: g[0] - g[7] (H2U[g[0]] 28) | (H2U[g[1]] 24) | ... | H2U[g[7]] // WORD Data2 4 hex digits: g[9] - g[12] (H2U[g[9]] 12) | ... | H2U[g[12]] // WORD Data3 4 hex digits: g[14] - g[17] (H2U[g[14]] 12) | ... | H2U[g[17]] // BYTE Data4[8] 16 hex digits: g[19]–g[36] (g[19], g[20]), (g[21], g[22]), ... (g[34], g[35])每一对十六进制字符被解析为一个字节。中间的 - 符号被跳过g[8], g[13], g[18], g[23] 是 -。因此整段是一个无分支、常量求值的 GUID 解析器 总结理解 这段代码的目的是为了让你能用字符串定义 GUID但 在编译期就能将字符串转化为真实的 GUID 对象。配合前面提到的 STRUCT_GUID 和 get_guid() 机制就可以对任意类型 T 实现 __uuidof(T) 的能力跨平台兼容。这种实现方式 既不依赖 RTTI也不增加对象大小且可静态验证和优化。 这段内容是 Clang 下使用 __uuidof() 和 GUID 的编译期模拟实现方案的延续解释了 str_to_guid() 机制的工作方式、潜在限制和一些高级用法。下面是逐条解释 理解要点 str_to_guid() 是 constexpr constexpr GUID str_to_guid(const GuidString g) noexcept;这是一个编译期函数所以只要传入的是字符串常量就能在编译时生成 GUID 实例。可用于 constexpr GUID value str_to_guid(...)不会有运行时代价。 get_guid() 依赖于 ADLArgument-Dependent Lookup templatetypename T constexpr GUID get_guid(T*);它通过 实参依赖查找 来解析 get_guid()。所以这个函数必须定义在和类型 T 同一个命名空间下。否则 get_guid(T*) 找不到合适的定义触发 static_assert() 编译错误这个是特意设计的安全机制。 若类型未定义 GUID会报错 templatetypename T constexpr GUID get_guid(T*) {static_assert(false, Type has no GUID.); }这是故意设计的“fail early”机制。目的是让开发者在使用 __uuidof(T) 时必须先注册 GUID否则就失败。 限制和已知问题 仅适用于 C11 这套方案依赖 C11 的 constexpr 和模板机制。不兼容更早的标准如 C03。 NDK 链接器问题在 Android 开发中 NDK linker error when __uuidof() is used as a template parameter 具体问题 templatetypename C, const IID* piid __uuidof(C) class QIPtr;在某些平台如 Android NDK__uuidof() 的地址值不能用于模板非类型参数。原因链接器无法静态推导 __uuidof(C) 的地址。 替代方案使用 resolve_guid_ptrC, piid::guid 解决方法 templatetypename C, const IID* piid nullptr class QIPtr {static constexpr const GUID* guid resolve_guid_ptrC, piid::guid; };提供一个 resolve_guid_ptr 模板 如果显式提供 piid就用它。如果为 nullptr就自动使用 __uuidof(C)。 这个模式使用了 偏特化/特化技巧 来绕开链接器问题。 总结 这套 Clang 下的 GUID 实现机制的关键点是 特性说明str_to_guid()编译期解析 GUID 字符串为结构体。get_guid() ADL自动查找对应类型的 GUID。如果没有定义则编译失败。Clang 支持跨平台 __uuidof通过 #define __uuidof(type) guid_oftype::value 实现替代。NDK 问题的解决使用 resolve_guid_ptr 延迟和间接获取 GUID 地址绕过链接器限制。 对整套跨平台 GUID 关联机制的总结性说明下面是它的要点解析和中文理解 总结理解 STRUCT_GUID 的作用 STRUCT_GUID 允许在多个平台如 VC 和 Clang上将字符串形式的 GUID 与类型关联。 在 Visual C 下使用 __declspec(uuid(...))。在 Clang 下通过 get_guid() 和 str_to_guid() 编译期计算 GUID。它本质上是一个跨平台的类型→GUID映射工具。 保持与旧代码兼容 可以继续使用 __uuidof()。 __uuidof(T) 在 Visual C 是内建的。在 Clang 中通过 #define __uuidof(type) guid_oftype::value 来兼容。所以老代码无需修改新的平台仍然能运行。 这个技巧还能用于其他自定义类型属性 不局限于 GUID你还可以用类似方式为类型添加其他属性如 类型标签tag分类信息traits序列化 ID 等等 如何实现一个通用机制 定义一个宏比如 STRUCT_GUID来注入属性信息。宏会展开成一个 constexpr 函数返回这个属性值。提供一个访问接口类或模板如 guid_ofT::value。提供一个默认模板函数当类型未定义该属性时触发 static_assert或返回默认值。 中文总结一句话 使用 STRUCT_GUID 技术我们可以为类型编译期地绑定 GUID 或其他自定义属性支持多平台编译器如 VC、Clang且对旧代码兼容良好。这个机制也能扩展到任意类型属性的静态绑定是一种强大且通用的元编程手法。
http://www.zqtcl.cn/news/412550/

相关文章:

  • 电子商务网站建设的试卷设计之家app
  • 抚养网站建设黔东南小程序开发公司
  • 网站建设相关行业有哪些wordpress 内容管理系统
  • 网站 备案地温州网站优化排名推广
  • 做网站的工作量国内 wordpress
  • 定制网站开发是什么大业推广网站
  • 网站建设每年需要交多少钱天津制作网站公司
  • 网站平台都有哪些wordpress 主题制作 视频
  • 中山网站建设方案家具网站开发目的
  • 教师个人网站建设建模培训多少钱
  • 个人网站可以做社交类型网站建设功能说明书
  • 微站是什么移动网站 拉新
  • 黑龙江省农业网站建设情况wordpress4.94主题上传不显示
  • 个人网站的域名重庆建立公司网站
  • 什么做网站做个多少钱啊百度网盘app
  • 做网站的公司挣钱吗石家庄房产
  • 烟台网站建设设计公司安徽建设工程信息网查询平台蔡庆树
  • 微信链接的微网站怎么做西安企业网站制作价格
  • uniapp怎么做淘客网站表格布局的网站
  • wordpress侧栏图片插件提升seo搜索排名
  • 如何查询网站的域名注册邹城建设银行网站
  • 招生门户网站建设方案国家企业信用信息公示信息查询网
  • 用dw做淘客网站的步骤移动互联网应用技术
  • 企业合作的响应式网站石家庄网站建设推广
  • 成都网站排名优化开发广告传媒公司简介模板
  • 中山网站建设企业网站内容建设
  • 免费网站建站页面wordpress的主题在哪个文件夹
  • 国企网站建设要求站长之家排行榜
  • 做视频网站利润如何处理旅游电子商务网站建设技术规范
  • 做网站架构网页浏览器怎么卸载