COM接口规则的存在是有原因的
可能有些人认为接口上的 COM 接口规则没有必要设计的那么严格,但我想说的是,这些规则的存在是有原因的。
假设你在你的产品代码中新增加了版本号为 N 的接口,由于这个接口是内部使用的,没有任何公开文档。所以你可以随意修改它,而不会打破任何不兼容性。
但是需要注意的是,如果你修改一个接口,则必须要生成一个新的接口标识符(IID),因为一个接口标识符唯一标识了这个接口(正如它的名字所暗示的那样)。
以上这条规则,即使是对于内部接口也是一样。
假设你决定不遵循这一规则,在 N + 1 版本的接口中继续使用 N 版本相同的 IID,由于这是一个内部使用的借口,应该不会造成什么大影响。
直到你需要为这两个版本编写一个补丁,事情就不太妙了。
这个补丁会出现这样的问题:它可以调用 IUnknown::QueryInterface 方法并传入这个 IID,COM 库会返回一些东西。但是你不会知道返回的是 N 版本的接口,还是 N + 1 版本的接口。如果你没有意识到这一点,则你的补丁代码很可能会假设返回的是 N + 1 版本的接口,这个时候,如果实际的接口是 N 版本的话,一些奇怪的事情就会发生。
调试这类问题不太好玩,相信我,修复它也不太容易。
你的补丁必须使用其他一些提示来决定它实际返回的接口。如果程序以前已打过补丁,则需要具有每个补丁的版本号,以便确定所拥有的接口版本。
请注意,此依赖项可以隐藏在其他接口后面。考虑下面的代码:
>> 请移步至 topomel.com 以查看图片 <<
假设你要向 IColorInfo 接口添加一个新方法:
>> 请移步至 topomel.com 以查看图片 <<
由于改变了接口,但同时也改变了IID,所以一切都很好,对吧?
非也!
IGraphicImage 接口依赖于 IColorInfo 接口。当你修改 IColorInfo 接口时,也隐式更改了
IGraphicImage::GetColorInfo 方法,因为返回的接口现在是 N + 1 版本的 IColorInfo 接口。
考虑使用 N + 1 版本的头文件编写的补丁程序。
>> 请移步至 topomel.com 以查看图片 <<
如果针对 N 版本运行,则对
IGraphicImage::GetColorCount 的调用将返回 N 版本的 IColorInfo,并且该版本不支持 IColorInfo::AdjustColor 方法。但无论如何你调用它。结果就是: 访问 N 版本的虚函数表的结尾并造成访问违规。
快速的解决方案是,修改 IGraphicImage 的 IID,以反映它所依赖的 IColorInfo 接口上的更改。
>> 请移步至 topomel.com 以查看图片 <<
更可靠的解决方法是,修改
IGraphicImage::GetColorInfo 方法,以便传递要接收的接口。
>> 请移步至 topomel.com 以查看图片 <<
这允许更改 IGraphicImage 所依赖的接口,而无需更改 IGraphicImage 接口本身。当然,实现需要改变以响应IID_IColorInfo 的新值。但是现在调用者可以放心,因为当它请求接口时,它实际上是在获取它,而不是巧合地具有相同名称的其他东西。
总结
我从过去伤痕累累的经历中只学会了一件事: 接口一经对外发布,就只能扩展,不能再修改。你得为你的客户想想。
成也 COM,败也 COM。
最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《The COM interface contract rules exist for a reason》

相关文章:
COM接口规则的存在是有原因的
可能有些人认为接口上的 COM 接口规则没有必要设计的那么严格,但我想说的是,这些规则的存在是有原因的。 假设你在你的产品代码中新增加了版本号为 N 的接口,由于这个接口是内部使用的,没有任何公开文档。所以你可以随意修改它&a…...
并行分布式计算 并行计算性能评测
文章目录 并行分布式计算 并行计算性能评测基本性能指标参数CPU 基本性能指标存储器性能并行与存储开销 加速比性能定律Amdahl 定律Gustafson 定律Sun 和 Ni 定律加速比讨论 可括放性评测标准等效率度量标准等速度度量标准平均延迟度量标准 基准评测程序(Benchmark&…...
[网络安全]XSS之Cookie外带攻击姿势及例题详析
[网络安全]XSS之Cookie外带攻击姿势及例题详析 概念姿势及Payload启动HTTP协议 method1启动HTTP协议 method2 例题详析Payload1Payload2window.open 总结 本文仅分享XSS攻击知识,不承担任何法律责任。 本文涉及的软件等请读者自行安装,本文不再赘述。 概…...
Angular之创建项目报错:setTimeout is not defined
零基础的宝们,跟着视频学习Angular中,会教授大家如何创建一个新项目。 但是在操作时就会遇到无法创建的问题。 接下来我们一起来看看,本人Angular起步时卡在家门口的问题。 在已经安装了nodejs的情况下,被建议使用cnpm命令全局安装…...
python实现神经网络之---构建神经元模型1(python3.7)
本文主要要以周志华的机器学习书为蓝本编写 第5章神经网络 5.1python 实现神经元模型 神经网络中最基本的成分是神经元 (neuro且)模型,如下图所示: 1943 年, [McCulloch and Pitts, 1943] 将上述情形抽象为国 5.1所示的简单模型,…...
前端面试题 —— JavaScript (三)
一、JavaScript有哪些内置对象 全局的对象( global objects )或称标准内置对象,不要和 "全局对象(global object)" 混淆。这里说的全局的对象是说在全局作用域里的对象。全局作用域中的其他对象可以由用户的…...
【openGauss】一键编译openGauss5.0+dolphin,体验新增的mysql兼容特性
脚本 新建一个/opt/onekey-build-og.sh文件,存入以下内容 #!/bin/bash # 环境 centos 7.9 4C 8G (配置越高编译越快,4G内存编译不了,磁盘大概需要14GB) # 安装一些依赖 (libaio-devel如果不卸载重装,可能会找不到io_c…...
【LeetCode - 每日一题】1073. 负二进制数相加 (2023.05.18)
1073. 负二进制数相加 题意 基数为 -2 。实现两个 0/1 数组串的加法。 解法 这是一道模拟题。 设 arr1[i] 和 arr2[i] 是数组 arr1 和 arr2 从低到高的第 i 位数。 首先回顾普通的二进制数的相加,从低位开始计算,在计算的同时维护用一个变量 carry…...
软件上线会面临哪些缺陷?这四种你一定很熟悉
上线对任何软件产品来说都是一件大事,确保一切正常并且向用户发布高质量的软件非常重要。劣质、过早、不稳定、难以使用的产品会产生大量经济损失,也可能使用户对品牌本身失去信任。一直以来,我们都说应该测试,应该将缺陷修复到可…...
html监听界面被隐藏或显示
vue相比于小程序和uni-app 显然少了两个有点用的生命周期 onShow 应用被展示 onHide 应用被隐藏 但其实这个 要做其实也很简单 JavaScript中 有对应的visibilitychange事件可以监听 我们Html参考代码如下 <!DOCTYPE html> <html lang"en"> <head>…...
Springboot启动失败 DB连不上竟然是maven配置的问题
Springboot启动失败:Failed to instantiate [javax.sql.DataSource]。 最开始以为是DB版本后,需要升级驱动版本,但更新驱动版本还是不行,而且另外一个项目同样驱动同样配置可以启动。 后面发现代码读取不到yml文件中的配置信息。…...
P9234 [蓝桥杯 2023 省 A] 买瓜 题解
题目传送门 前言 说实话这题根本用不到什么折半……,今天看机房大佬写了半天加了一堆剪枝还以为很难,其实是你们想复杂了 20分钟不到从看题到代码实现 这题其实只需要可行性剪枝加排序 哦还有个后缀和 进入正题 小木棍子都听说过吧 没错就是小波上…...
ThingsBoard自定义分发节点duplicate to related
------------------------------------内容仅博主所有,订阅者请勿泄露,感谢--------------------- 1、概述 大家好,我又更新干货了,还是那句话,我绝不像某些博主“拿我格子衫”分享那些照抄官网翻译的东西来骗订阅,我觉得那是浪费时间,要搞就搞干货,今天给大家分享Th…...
vim自动更新ctags与taglist
vim的 ctags 和 taglist 在默认情况下是不进行自动更新的,这对于编写代码是非常不方便的,好在vim的脚本还是很强大的,于是在vimrc中添加如下函数: function! UpdateCtags()let curdirgetcwd()while !filereadable("./tags&qu…...
linux查看日志常用命令,动态日志命令
linux查看日志命令,动态日志命令: tail: -n是显示行号;相当于nl命令;例子如下: tail -100f test.log 实时监控100行日志。 tail -n 10 test.log 查询日志尾部最后10行的日志。 tail -…...
分段存储管理方式
目录 一、分段存储管理方式的引入的需求: 1.方便编程 2.信息共享 3.信息保护 4.动态增长 5.动态链接 二、分段系统的基本原理 1.分段 2.段表 3.地址变换机构 4.分页与分段的主要区别 三、信息共享 四、段页式存储管理方式 1.基本原理 2.地址变换过程 分段与分页…...
将nacos从本地切换到远程服务器上时报错:客户端端未连接,Client not connected
报错信息: 09:34:38.438 [com.alibaba.nacos.client.Worker] ERROR com.alibaba.nacos.common.remote.client - Send request fail, request ConfigBatchListenRequest{headers{charsetUTF-8, Client-AppNameunknown, Client-RequestToken65c0fbf47282ae0a7b85178…...
系统掌握入河排污口设置论证技术、方法及报告编制框架
在短时间内较系统的掌握入河排污口设置论证技术、方法及报告编制框架,学习内容以城镇生活污水厂、造纸项目、石化项目、制药项目案例为线索,系统讲解入河排污口设置论证报告书编制过程,并以水质模型为手段,讲解水质影响预测模型的…...
服务端渲染
服务端渲染 和 前后端分离! 渲染 什么是渲染呢 ? 其实很简单, 就是把数据反应在页面上,说白了, 就是利用 js 的语法, 把某些数据组装成 html 结构的样子, 放在页面上展示。 举个例子 : 1. 准备一段 html 结构 <h1>hello world</h1> <di…...
干货丨警惕!14个容易导致拒稿的常见错误
Hello,大家好! 这里是壹脑云科研圈,我是喵君姐姐~ 从做研究、到写论文、再到投稿,每一步都是巨大的挑战。以下列举了一些在这些过程中可能导致拒稿的常见错误,希望能帮助大家避开。 01 格式问题 1.没有遵守投稿须知 期刊提供了…...
斐波那契数列优化实战:从递归到迭代的预防性维护技巧
斐波那契数列优化实战:从递归到迭代的预防性维护技巧 在软件开发中,我们常常会遇到一些看似简单却暗藏性能陷阱的经典问题。斐波那契数列计算就是这样一个典型案例——它可以用几行递归代码轻松实现,但当n值增大时,性能会急剧下降…...
写算法咖啡拉花模板,一键成型,输出:咖啡师/家用都可用。
利用激光切割的高精度,制作出不锈钢或食品级亚克力的镂空模板(Stencil),让即便是新手,也能一键复刻大师级的拿铁艺术。以下是完整的项目交付文档:项目名称:LatteArt-Stencil-Gen (咖啡拉花模板生…...
Python Web开发入门(二十一):完整前后端项目实战——从零构建企业级电商系统
一、前言:为什么需要一个完整的实战项目? 有读者在评论区问:"学了这么多天,感觉知识点很散,怎么把它们串联起来?" 我的回答是:真正的学习发生在实战中,特别是当你要把多个模块有机组合成一个可运行的系统时。 让我分享一个真实故事:2025年,我带团队重构…...
终极指南:如何用APK-Installer在Windows上快速安装安卓应用
终极指南:如何用APK-Installer在Windows上快速安装安卓应用 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经想在Windows电脑上运行安卓应用&…...
毕业季自救指南:用百考通AI告别论文焦虑,高效搞定学术写作
当论文截止日期步步紧逼,你是否正在经历深夜查文献、反复修改格式、为降重焦头烂额的无助时刻?或许,你需要的不仅是一杯咖啡,更是一个懂学术、更懂你的智能伙伴。 深夜两点,图书馆的灯光依然零星亮着。电脑屏幕上闪烁的…...
逆向分析新姿势:用VMOSPro虚拟环境绕过APP证书校验(小黄鸟抓包+XP框架联动教程)
移动应用安全分析:虚拟环境下的流量捕获技术解析 在移动应用安全研究领域,绕过证书校验机制一直是分析加固应用的关键突破口。传统真机环境由于系统限制和安全策略,往往难以对采用SSL Pinning等防护措施的应用进行有效流量分析。而虚拟化技术…...
DAMOYOLO-S应用场景:视频流抽帧检测+时间轴标注的轻量方案
DAMOYOLO-S应用场景:视频流抽帧检测时间轴标注的轻量方案 1. 引言:从单张图片到视频流的挑战 如果你用过一些目标检测工具,可能会发现一个普遍现象:它们大多只擅长处理单张图片。你上传一张照片,它给你标出里面的物体…...
技术管理中的目标设定与绩效评估
技术管理中的目标设定与绩效评估:驱动团队高效创新的核心 在快速发展的技术领域,目标设定与绩效评估是管理团队、推动创新的关键工具。明确的目标能够为技术团队提供方向,而科学的绩效评估则能确保资源高效利用,激发成员潜力。无…...
Claude Code Harness架构技术深度解析:生产级AI Agent工程化实践
技术分析:基于泄露源码的Claude Code Harness设计原理与工程实现细节 前言:AI Agent工程化的技术挑战 2026年,Claude Code源代码泄露事件揭示了Anthropic在AI Agent工程化方面的深度技术积累。本文基于泄露的TypeScript源码,从技…...
DeepSeek-R1-Distill-Qwen-1.5B实战:快速搭建智能对话服务
DeepSeek-R1-Distill-Qwen-1.5B实战:快速搭建智能对话服务 1. 模型介绍与核心优势 DeepSeek-R1-Distill-Qwen-1.5B是DeepSeek团队基于Qwen2.5-Math-1.5B基础模型,通过知识蒸馏技术融合R1架构优势打造的轻量化版本。该模型在保持高性能的同时࿰…...
