活动介绍

COM编程:从接口定义到服务器实现

立即解锁
发布时间: 2025-08-20 01:59:30 阅读量: 1 订阅数: 3
PDF

COM+编程实战:使用Visual C++和ATL构建企业级应用

### COM编程:从接口定义到服务器实现 #### 接口封送与内存管理 接口封送是COM编程中的重要环节,它有两种方式:基于MIDL生成代码的标准封送和自定义封送。标准封送性能高效,可由MIDL生成的代理/存根代码或类型库驱动。 - **代理/存根DLL**:需编译和链接以创建,要在客户端和服务器机器上注册。使用`regsvr32.exe`工具进行注册和注销操作,示例如下: ```plaintext regsvr32.exe myproxystub.dll // 注册代理/存根到本地机器 regsvr32.exe –u myproxystub.dll // 注销代理/存根 ``` 若使用ATL创建COM服务器项目,ATL会生成模块定义文件和生成文件;若不使用ATL,可使用CreatePS实用工具。 - **类型库驱动的封送**:接口方法参数需使用自动化兼容类型,接口应标记为`oleautomation`或`dual`,类型库要在客户端和服务器机器上注册,可使用SDK提供的`LoadTypeLibEx` API进行注册。负责类型库封送的基础设施是通用封送器,目前实现在`OLEAUT32.DLL`中。 需注意,封送发生在接口级别,一个接口不能有多种封送机制,且只应注册代理/存根DLL或类型库中的一个。 在内存管理方面,参数的方向属性决定了客户端和服务器的角色: | 参数类型 | 内存分配 | 内存释放 | | ---- | ---- | ---- | | [in] | 客户端 | 客户端 | | [out] | 服务器 | 客户端 | | [in, out] | 客户端 -> 服务器 -> 服务器 | 客户端 | 常用的内存管理API包括: - 对于`BSTR`:`SysAllocString`、`SysReAllocString`、`SysFreeString`等。 - 对于`VARIANT`:`VariantInit`和`VariantClear`。 - 对于原始内存:`CoTaskMemAlloc`、`CoTaskMemReAlloc`和`CoTaskMemFree`。 以下代码展示了服务器端分配内存和客户端释放内存的过程: ```cpp // Server code STDMETHODIMP CMyExplore::GetMyLeaders(MYLEADERS *pDataArray) { pDataArray->lElements = 2; // 原始内存分配 pDataArray->pData = (MYLEADER*) ::CoTaskMemAlloc(2 * sizeof(MYLEADER)); // BSTR分配 pDataArray->pData[0].bsFirstName=SysAllocString(L"Mohandas"); pDataArray->pData[0].bsLastName=SysAllocString(L"Gandhi"); // VARIANT中的BSTR分配 VARIANT& v0 = pDataArray->pData[0].vTitle; ::VariantInit(&v0); V_VT(&v0) = VT_BSTR; V_BSTR(&v0) = ::SysAllocString(L"Mahatma"); // BSTR分配 pDataArray->pData[1].bsFirstName=SysAllocString(L"Winston"); pDataArray->pData[1].bsLastName=SysAllocString(L"Churchil"); // VARIANT中的BSTR分配 VARIANT& v1 = pDataArray->pData[1].vTitle; ::VariantInit(&v1); V_VT(&v1) = VT_BSTR; V_BSTR(&v1) = ::SysAllocString(L"Sir"); return S_OK; } // Client code fragment MYLEADERS leaders; HRESULT hr = pMyExplore->GetMyLeaders(&leaders); // 释放内存 for(i=0; i<leaders.lElements; i++) { MYLEADER* pLeader = &leaders.pData[i]; ::VariantClear(&pLeader->vTitle); // 释放VARIANT中的BSTR ::SysFreeString(pLeader->bsFirstName); // 释放BSTR ::SysFreeString(pLeader->bsLastName); // 释放BSTR } ::CoTaskMemFree(leaders.pData); // 释放原始内存分配 ``` 为减少人为错误,可使用ATL提供的包装类,如`CComBSTR`和`CComVariant`。 #### 多IDL文件组织与接口定义 在COM开发中,常需处理多个IDL文件。为避免接口定义错误和维护困难,理想情况下接口应定义在一个文件中,其他IDL文件可使用`import`关键字引用。常见的做法是在IDL文件开头导入`oaidl.idl`和`ocidl.idl`: ```idl import "oaidl.idl"; import "ocidl.idl"; ``` 为防止类型库中定义重复,需使用`importlib`关键字,如导入`stdole2.tlb`和`stdole32.tlb`: ```idl importlib("stdole32.tlb"); importlib("stdole2.tlb"); ``` 接下来,将C++接口转换为IDL接口,步骤如下: 1. **创建文件**:使用记事本或喜欢的编辑器创建`video.idl`文件。 2. **访问SDK定义的IDL文件**: ```idl import "oaidl.idl"; import "ocidl.idl"; ``` 3. **定义接口块**: ```idl [ ] interface IVideo : IUnknown { }; ``` 4. **添加接口属性**:必需的属性是`object`和`uuid`,建议添加`helpstring`和`pointer_default`。可使用`guidgen.exe`获取接口的GUID: ```idl [ object, uuid(318B4AD0-06A7-11d3-9B58-0080C8E11F14), helpstring("IVideo Interface"), pointer_default(unique) ] ``` 5. **添加接口方法**: ```idl interface IVideo : IUnknown { HRESULT GetSignalValue([out] long* val); }; ``` 6. **添加方法属性**: ```idl interface IVideo : IUnknown { [helpstring("Obtain the signal value")] HRESULT GetSignalValue([out] long* val); }; ``` 7. **重复步骤3 - 6定义`ISVideo`接口**: ```idl [ object, uuid(318B4AD1-06A7-11d3-9B58-0080C8E11F14), helpstring("ISVideo Interface"), pointer_default(unique) ] interface ISVideo : IUnknown { [helpstring("Obtain the S-Video signal value")] HRESULT GetSVideoSignalValue([out, retval] long* val); }; ``` 8. **定义库块**: ```idl [ ] library VcrLib { }; ``` 9. **添加库属性**:必需属性是`uuid`,建议添加版本号和`helpstring`: ```idl [ uuid(318B4AD2-06A7-11d3-9B58-0080C8E11F14), version(1.0), helpstring("VCR Type Library") ] ``` 10. **添加`importlib`语句**: ```idl library VcrLib { importlib("stdole32.tlb"); importlib("stdole2.tlb"); }; ``` 11. **添加`coclass`块**: ```idl [ ] coclass VCR { }; ``` 12. **定义`coclass`属性**:必需属性是`uuid`,建议添加`helpstring`: ```idl uuid(318B4AD3-06A7-11d3-9B58-0080C8E11F14), helpstring("VCR Class") ``` 13. **列出要公开的接口**: ```idl interface IVideo; interface ISVideo; ``` 最终的`Video.idl`文件如下: ```idl // File Video.idl import "oaidl.idl"; import "ocidl.idl"; [ object, uuid(318B4AD0-06A7-11d3-9B58-0080C8E11F14), helpstring("IVideo Interface"), pointer_default(unique) ] interface IVideo : IUnknown { [helpstring("Obtain the signal value")] HRESULT GetSignalValue([out, retval] long* val); }; [ object, uuid(318B4AD1-06A7-11d3-9B58-0080C8E11F14), helpstring("ISVideo Interface"), pointer_default(unique) ] interface ISVideo : IUnk ```
corwn 最低0.47元/天 解锁专栏
赠100次下载
继续阅读 点击查看下一篇
profit 400次 会员资源下载次数
profit 300万+ 优质博客文章
profit 1000万+ 优质下载资源
profit 1000万+ 优质文库回答
复制全文

相关推荐

李_涛

知名公司架构师
拥有多年在大型科技公司的工作经验,曾在多个大厂担任技术主管和架构师一职。擅长设计和开发高效稳定的后端系统,熟练掌握多种后端开发语言和框架,包括Java、Python、Spring、Django等。精通关系型数据库和NoSQL数据库的设计和优化,能够有效地处理海量数据和复杂查询。
最低0.47元/天 解锁专栏
赠100次下载
百万级 高质量VIP文章无限畅学
千万级 优质资源任意下载
千万级 优质文库回答免费看

最新推荐

【评估情感分析模型】:准确解读准确率、召回率与F1分数

![Python实现新闻文本类情感分析(采用TF-IDF,余弦距离,情感依存等算法)](https://img-blog.csdnimg.cn/20210316153907487.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpbGRu,size_16,color_FFFFFF,t_70) # 摘要 情感分析是自然语言处理领域的重要研究方向,它涉及从文本数据中识别和分类用户情感。本文首先介绍了情感分析模型的基本概念和评估指标,然后

【调试与性能优化】:LMS滤波器在Verilog中的实现技巧

![【调试与性能优化】:LMS滤波器在Verilog中的实现技巧](https://img-blog.csdnimg.cn/img_convert/b111b02c2bac6554e8f57536c89f3c05.png) # 摘要 本文详细探讨了最小均方(LMS)滤波器的理论基础、硬件实现、调试技巧以及性能优化策略,并通过实际案例分析展示了其在信号处理中的应用。LMS滤波器作为一种自适应滤波器,在数字信号处理领域具有重要地位。通过理论章节,我们阐述了LMS算法的工作原理和数学模型,以及数字信号处理的基础知识。接着,文章介绍了LMS滤波器的Verilog实现,包括Verilog语言基础、模块

MATLAB程序设计模式优化:提升pv_matlab项目可维护性的最佳实践

![MATLAB程序设计模式优化:提升pv_matlab项目可维护性的最佳实践](https://pgaleone.eu/images/unreal-coverage/cov-long.png) # 摘要 本文全面探讨了MATLAB程序设计模式的基础知识和最佳实践,包括代码的组织结构、面向对象编程、设计模式应用、性能优化、版本控制与协作以及测试与质量保证。通过对MATLAB代码结构化的深入分析,介绍了函数与脚本的差异和代码模块化的重要性。接着,本文详细讲解了面向对象编程中的类定义、继承、封装以及代码重用策略。在设计模式部分,本文探讨了创建型、结构型和行为型模式在MATLAB编程中的实现与应用

CListCtrl字体与颜色搭配优化:打造视觉舒适界面技巧

![CListCtrl字体与颜色搭配优化:打造视觉舒适界面技巧](https://anchorpointegraphics.com/wp-content/uploads/2019/02/ColorContrastExamples-02.png) # 摘要 本文深入探讨了CListCtrl控件在Windows应用程序开发中的应用,涵盖了基础使用、字体优化、颜色搭配、视觉舒适性提升以及高级定制与扩展。通过详细分析CListCtrl的字体选择、渲染技术和颜色搭配原则,本文提出了提高用户体验和界面可读性的实践方法。同时,探讨了视觉效果的高级应用,性能优化策略,以及如何通过定制化和第三方库扩展List

【BT-audio音频抓取工具比较】:主流工具功能对比与选择指南

# 摘要 本文旨在全面介绍BT-audio音频抓取工具,从理论基础、功能对比、实践应用到安全性与隐私保护等多个维度进行了深入探讨。通过分析音频信号的原理与格式、抓取工具的工作机制以及相关法律和伦理问题,本文详细阐述了不同音频抓取工具的技术特点和抓取效率。实践应用章节进一步讲解了音频抓取在不同场景中的应用方法和技巧,并提供了故障排除的指导。在讨论工具安全性与隐私保护时,强调了用户数据安全的重要性和提高工具安全性的策略。最后,本文对音频抓取工具的未来发展和市场需求进行了展望,并提出了选择合适工具的建议。整体而言,本文为音频抓取工具的用户提供了一个全面的参考资料和指导手册。 # 关键字 音频抓取;

【游戏物理引擎基础】:迷宫游戏中的物理效果实现

![基于C++-EasyX编写的益智迷宫小游戏项目源码.zip](https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/7eae7ef4-7fbf-4de2-b153-48a18c117e42/d9ytliu-34edfe51-a0eb-4516-a9d0-020c77a80aff.png/v1/fill/w_1024,h_547,q_80,strp/snap_2016_04_13_at_08_40_10_by_draconianrain_d9ytliu-fullview.jpg?token=eyJ0eXAiOiJKV1QiLCJh

【企业级应用高性能选择】:View堆栈效果库的挑选与应用

![View堆栈效果库](https://cdn.educba.com/academy/wp-content/uploads/2020/01/jQuery-fadeOut-1.jpg) # 摘要 堆栈效果库在企业级应用中扮演着至关重要的角色,它不仅影响着应用的性能和功能,还关系到企业业务的扩展和竞争力。本文首先从理论框架入手,系统介绍了堆栈效果库的分类和原理,以及企业在选择和应用堆栈效果库时应该考虑的标准。随后通过实践案例,深入探讨了在不同业务场景中挑选和集成堆栈效果库的策略,以及在应用过程中遇到的挑战和解决方案。文章最后展望了堆栈效果库的未来发展趋势,包括在前沿技术中的应用和创新,以及企业

STM8点阵屏汉字显示:用户界面设计与体验优化的终极指南

![STM8点阵屏汉字显示:用户界面设计与体验优化的终极指南](http://microcontrollerslab.com/wp-content/uploads/2023/06/select-PC13-as-an-external-interrupt-source-STM32CubeIDE.jpg) # 摘要 STM8点阵屏技术作为一种重要的显示解决方案,广泛应用于嵌入式系统和用户界面设计中。本文首先介绍STM8点阵屏的技术基础,然后深入探讨汉字显示的原理,并着重分析用户界面设计策略,包括布局技巧、字体选择、用户交互逻辑及动态效果实现等。接着,本文详细阐述了STM8点阵屏的编程实践,涵盖开

【发那科CNC SDK Demo源码深度解析】:掌握示例代码的秘密

![Focas1_2 SDK](https://i-blog.csdnimg.cn/blog_migrate/491af666dbb715c3e7da2f75b122fc24.png) # 摘要 本文介绍了发那科CNC SDK的核心理论和应用实践。首先概述了CNC机床的工作原理及其基本组成和控制逻辑,接着详细分析了SDK的功能架构、关键功能及其模块划分,并对示例代码的结构进行了深入探讨。此外,本文探讨了SDK代码的编译、运行环境搭建,以及核心功能实现的细节,并阐述了如何与其他系统或设备进行集成。在实践应用的基础上,本文进一步讨论了代码优化与故障排除的策略,并提出性能调优的建议。最后,文章展望

【wxWidgets多媒体处理】:实现跨平台音频与视频播放

![【wxWidgets多媒体处理】:实现跨平台音频与视频播放](https://media.licdn.com/dms/image/D4D12AQH6dGtXzzYAKQ/article-cover_image-shrink_600_2000/0/1708803555419?e=2147483647&v=beta&t=m_fxE5WkzNZ45RAzU2jeNFZXiv-kqqsPDlcARrwDp8Y) # 摘要 本文详细探讨了基于wxWidgets的跨平台多媒体开发,涵盖了多媒体处理的基础理论知识、在wxWidgets中的实践应用,以及相关应用的优化与调试方法。首先介绍多媒体数据类型与