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

调用com对象的坑

1、谏言

最近我在弄64位调用32位dll的问题,在几种IPC之间,最后考虑了调用COM 毕竟我们只在windows平台

2、第一坑–修改编译后都需要重新注册,注册表

一直以为只需要编译就好了,结果调用没反应、报错什么的,需要先撤销注册再进行注册

3、第二坑–多线程调用问题

由于我编写的一个操作 是主线程 创建了 com对象后,有个子线程会一直在后台死循环调用最后回调

我最开始按照传入COM指针去进行调用结果是 没反应 也不报错

反复测试后发现是
主线程调用就有反应
子线程调用就没反应

超级奇怪的问题 最后发现是COM多线程调用会出现问题需要一点操作

IGlobalInterfaceTable* GIT = nullptr;// 初始化(通常在主线程)
CoCreateInstance(CLSID_StdGlobalInterfaceTable, nullptr, CLSCTX_INPROC_SERVER,IID_IGlobalInterfaceTable, (void**)&GIT);// 注册接口
GIT->RegisterInterfaceInGlobal(read, IID_Name, &Cookie);

首先我们需要一个IGlobalInterfaceTable 的对象,然后注册具体的com对象,我们再在子线程里面进行的查找COM对象
去调用

HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
IICRead* pICRead = nullptr;
/*DWORD cookie = cookie;*/
reinterpret_cast<IGlobalInterfaceTable*>(GIT)->GetInterfaceFromGlobal((DWORD)Cookie, IID_Name, (void**)&pICRead);

这里 pICRead 就是我们查找出来的COM对象 这个对象和主线程是一样的

而我们要传递给子线程的 一个是IGlobalInterfaceTable 、 一个是 DWORD cookie 这个值很重要

是我们 RegisterInterfaceInGlobal 注册COM时的唯一标识符

子线程结束了需要调用COM的Release 与 CoUninitialize函数清除COM环境

当不再需要GIT时 我们一样需要Release 当然 之前我们还需要取消注册 RevokeInterfaceFromGlobal 参数是之前的那个cookie

4、第四坑–COM很多函数都是成对存在的


CoInitializeEx 与 CoUninitialize

RegisterInterfaceInGlobal 与 RevokeInterfaceFromGlobal

CoCreateInstance 与 Release

等等 只要用到COM对象 就需要清理

5、第五坑–COM读取数据块时

比如 现在我需要读取COM对象的函数 其中是返回一个数据块内部的数据的

我之前直接传入指针,发现返回出来的都是错误信息,一查才知道,有专门的手段

BYTE* pData = NULL;// 用于存储读取的数据
SAFEARRAY* p = SafeArrayCreateVector(VT_UI1, 0, 16);
read->Read_IC_Com(&p); // 读取数据到 SafeArray
SafeArrayAccessData(p, (void**)&pData); // 访问 SafeArray 数据
_memccpy(pDataBuff, pData, 0, 16); // 将 SafeArray 数据复制到 pDataBuff
SafeArrayUnaccessData(p);
SafeArrayDestroy(p);

我们需要使用 SafeArray 相关的东西 进行中转才可以

6、第六坑–多个线程同时调用COM对象可能会导致死锁,程序直接卡死

我写了一个这样的情况

我在com对象中写了个函数内部是死循环 条件 是可以通过另一个函数进行修改 从而达到可以结束的条件

问题就在这里了

我在子线程里面去调用这个COM跑死循环的函数

在主线程里面去调用这个可以结束COM死循环的条件函数

然后程序直接卡死

最后我修改死循环来到COM的调用方解决这个问题

http://www.dtcms.com/a/315516.html

相关文章:

  • 自由学习记录(77)
  • 【递归完全搜索】USACO Bronze 2023 January - 牛栏降温 IIAir Cownditioning II
  • 水库安全“守护者”:智能雨水情监测预报系统
  • 联发科芯片组曝高危漏洞:越界写入缺陷危及智能手机与物联网设备安全
  • 论文阅读笔记:《Curriculum Coarse-to-Fine Selection for High-IPC Dataset Distillation》
  • table行内--图片预览--image
  • 防御保护07-08
  • 2025年服务器漏洞生存指南:从应急响应到长效免疫的实战框架
  • 多层Model更新多层ListView
  • 4. 什么是字节码采用字节码的好处是什么
  • avue---upload 图片上传
  • 南柯电子|直流电机EMC整改:从干扰源到解决方案的实战指南
  • DHCP 握手原理
  • Laravel The requested URL /hellowzy was not found on this server. 404 问题的解决
  • gRPC Keepalive 机制详解与最佳实践
  • 本地部署文档管理平台 BookStack 并实现外部访问( Windows 版本)
  • C# LINQ(标准询运算符)
  • Windows 电脑远程访问,ZeroTier 实现内网穿透完整指南(含原理讲解)
  • 汽车OBD定位器:即插即用车辆管理省心又实用
  • CodeBuddy IDE 使用测评——半小时做一个web可视化数据工具
  • 数据可视化发展历程
  • eclipse类IDE导入现有工程教程
  • 分布式CAP定理
  • Java 中抽象概念的全面解析与实战指南
  • Python爬虫09_Requests用bs4进行数据解析
  • 【科研绘图系列】R语言绘制误差棒图
  • 【C++】模板深入进阶
  • 通信算法之298: verilog语法generate和for介绍
  • 深入浅出:Ajax 与 Servlet 实现前后端数据交互
  • VUE+SPRINGBOOT从0-1打造前后端-前后台系统-登录实现