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.没有遵守投稿须知 期刊提供了…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
