关于COM组件部分总结



软件工程的核心:模块化,最理想的情况是100%内聚0%耦合。
COM技术:微软公司的最高级二进制通讯规范,COM和DLL一样都是基于二进制的代码重用,其本身也就是DLL
 用于软件组件间跨进程,跨机器,和操作系统进行交互操作。COM是透明位置的。它
 可以在EXE,DLL或者远程机器上使用。
 
 
 
ATL COM应用
http://my.oschina.net/u/1024767/blog/352647
1、打开VS2010,新建ATL COM 项目,步骤:“文件” --》“新建” --》“项目”,选择“Visual C++” --》“ATL 项目” ,填写“名称” FirstCOM --》“确定”。
2、ATL 项目向导,勾选 【支持COM+ 1.0】和【支持部件注册器】,其他默认,点击完成。
3、切换到类视图,右键单击项目“FirstCOM”--》“添加”  --》“类”。
4、选“ATL”  --》“ATL 简单对象” --》“添加”。
5、ATL  简单对象向导,“简称”中输入类名称FirstClass,其他输入框会自动填写,最下面的“ProgID”没有自动填写,最好自己写上一个,如FirstCOM.math,否则后面无法正确调用组件,点击“完成”。如果出现提示【是否覆盖现有文件】,点击【是】即可。
6、切换到类视图,选中刚才添加的接口IFirstClass,如下,然后右键单击【添加】添加方法。
7、添加方法向导,在"方法名"  下输入Add。增加两个输入参数:勾选【in】,选择参数类型LONG,输入参数名para1,点击“添加”。同样操作增加参数para2。然后增加一个返回参数:先选择参数类型LONG*,再勾选【retval】,输入参数名result,点击添加。点击“完成”即可,如果点击下一步,不需要填写信息,点击“完成”即可。
8、切换到解决方案资源管理器,展开项目“源文件”, 双击 FirstCom.idl 打开IDL定义文件,看到如下代码,就是定义的COM方法了。
9、双击打开FirstClass.cpp  编辑代码:*result = para1 + para2;
10、编译运行,会生成dll文件,并自动注册到系统中。
问题及解决方法

问题1:我在Win64位系统中编译的,出现错误:无法打开预编译头文件:“Debug\FirstCOM.pch”:No such file or directory。
解决:右键点击你创建的项目,选择“属性”,弹出“FirstCOM 属性页”,在左侧展开"配置属性"--》展开“C/C++”--》选中“预编译头”,在右边的“预编译头”下拉菜单中选择“不使用预编译头文件”,点击“确定”按钮退出。
原因分析:编译器一般都是以文件为单位进行编译,如果修改了工程中的一个文件,那么将导致所有文件都要重新编译,这样的编译将耗费很长时间。为了提高编译速度,将那些不常被修改,比较稳定,文件单独包含到一个指定的头文件中, 然后生成一个预编译头文件 *.pch 。 VC++中默认的头文件为 stdAfx.h, 但光有头文件无法编译,所以还要用到StdAfx.cpp,StdAfx.cpp里只包含一句有效代码,这样编译时,通过编译  stdAfx.cpp就把大部分系统头文件编译进来, Debug目录下便会产生一个 存储了预编译信息的 *.pch 文件。如果 *.pch文件损坏或者不存在,就会出现“问题1”所示的无法打开预编译头文件的错。
如需深究,可参考博客:无法打开包括文件:“Stdfx.h

问题2:解决了问题1之后,又出现:error MSB8011: 未能注册输出。请尝试启用“逐用户重定向”,或者使用提升的权限从命令提示符处注册该组件。
解决: 项目-》属性-》链接器-》逐用户重定向--》设置为 true  (该方案网上常见,但仍“未能”根本解决问题)
分析: 由于win7权限问题,所以出现问题3,需要通过使用命令提示符来帮助注册该组件。

问题3:无法启动程序:“I:\VS Project\FirstCOM\Debug\FirstCOM.dll”。
解决:程序 --》 附件 --》 命令提示符,在”命令提示符“上点击鼠标右键,选择”以管理员身份运行“命令,这个时候将打开Dos命令窗口。
接下来输入:regsvr32   “I:\VS Project\FirstCOM\Debug\FirstCOM.dll”  (就是 regsvr32+.dll文件所在的完全路径了,全路径最好用引号括起来)
按 Enter 键,就能够注册成功了。

COM DLL 使用方式:
*1.界面程序:类视图中选中当前对话框类->右键添加类->MFC->TypeLib中的MFC类
*2.动态链接库的动态加载:
 #include "atlcomcli.h" 
 #import "FirstCOM.dll" no_namespace 

重要解释:
LoadLibrary
 一般是动态加载DLL时(你并不需要对应的头文件,和LIB),显示加载dll中函数,前提是你自己对dll导出的函数参数很了解.

 #pragma comment
一般是静态加载DLL时(对应的头文件、DLL,和LIB缺一不可,并且生产的EXE没有找到DLL文件就会导致“应用程序初始化失败”)

#import
 导入的dll是com组建的dll,主要用来解析com组建内部结构,便与c++识别调用



组件基础 1 软件开发的阶段 1.1 结构化编程 采用自顶向下的编程方式,划分模块 和功能的一种编程方式。 1.2 面向对象编程 采用对象的方式,将程序抽象成类, 模拟现实世界,采用继承、多态的方式 设计软件的一种编程方式。 1.3 面向组件编程 将功能和数据封装成二进制代码,采用 搭积木的方式实现软件的一种编程方式。 2 组件和优点 2.1 组件 - 实际是一些可以执行的二进 制程序,它可以给其他的应用程序、操 作系统或其他组件提供功能 2.2 优点 2.2.1 可以方便的提供软件定制机制 2.2.2 可以很灵活的提供功能 2.2.3 可以很方便的实现程序的分布式 开发。 3 组件的标准 - COMComponent Object Model ) 3.1 COM是一种编程规范,不论任何开发语言 要实现组件都必须按照这种规范来实现。 组件和开发语言无关。 这些编程规范定义了组件的操作、接口的 访问等等。 3.2 COM接口 COM接口是组件的核心,从一定程度上 讲"COM接口是组件的一切". COM接口给用户提供了访问组件的方式. 通过COM接口提供的函数,可以使用组件 的功能. 4 COM组件 4.1 COM组件-就是在Windows平台下, 封装在动态库(DLL)或者可执行文件(EXE) 中的一段代码,这些代码是按照COM的 规范实现. 4.2 COM组件的特点 4.2.1 动态链接 4.2.2 与编程语言无关 4.2.3 以二进制方式发布 二 COM接口 1 接口的理解 DLL的接口 - DLL导出的函数 类的接口 - 类的成员函数 COM接口 - 是一个包含了一组函数指针 的数据结构,这些函数是由组件实现的 2 C++的接口实现 2.1 C++实现接口的方式,使用抽象类 定义接口. 2.2 基于抽象类,派生出子类并实现 功能. 2.3 使用 interface 定义接口 interface ClassA { }; 目前VC中,interface其实就是struct 3 接口的动态导出 3.1 DLL的实现 3.1.1 接口的的定义 3.1.2 接口的实现 3.1.3 创建接口的函数 3.2 DLL的使用 3.2.1 加载DLL和获取创建接口的函数 3.2.2 创建接口 3.2.3 使用接口的函数 4 接口的生命期 4.1 问题 在DLL中使用new创建接口后,在用户 程序使用完该接口后,如果使用delete 直接删除,会出现内存异常. 每个模块有自己的内存堆(crtheap) EXE - crtheap DLL - crtheap new/delete/malloc/free默认情况 下都是从自己所在模块内存堆(crtheap) 中分配和施放内存.而各个模块的 这个内存堆是各自独立.所以在DLL中 使用new分配内存,不能在EXE中delete. 4.2 引用计数和AddRef/Release函数 引用计数 - 就是一个整数,作用是 表示接口的使用次数 AddRef - 增加引用计数 +1 Release - 减少引用计数 -1, 如果 当引用计数为0,接口被删除 4.3 使用 4.3.1 创建接口 4.3.2 调用AddRef,增加引用计数 4.3.3 使用接口 4.3.4 调用Release,减少引用计数 4.4 注意 4.4.1 在调用Release之后,接口指针 不能再使用 4.4.2 多线程情况下,接口引用计数 要使用原子锁的方式进行加减 5 接口的查询 5.1 每个接口都具有唯一标识 GUID 5.2 实现接口查询函数 QueryInterface 6 IUnknown 接口 6.1 IUnknown是微软定义的标准接口 我们实现所有接口就是继承这个接口 6.2 IUnknown定义了三个函数 QueryInterface 接口查询函数 AddRef 增加引用计数 Release 减少引用计数 7 接口定义语言 - IDL(Interface Definition Language ) 7.1 IDL和MIDL IDL - 定义接口的一种语言,与开发 语言无关. MIDL.EXE - 可以将IDL语言定义接口, 编译成C++语言的接口定义 7.2 IDL的基础 import "XXXX.idl" [ attribute ] interface A : interface_base { } 7.2.1 Import 导入,相当于C++的 #include 7.2.2 使用"[]"定义区域,属性描述 关键字 1) object - 后续是对象 2) uuid - 定义对象GUID 3) helpstring - 帮助信息 4) version - 版本 5) point_default - 后续对象 中指针的默认使用方式 比如: uniqune - 表示指针可以 为空,但是不能修改 7.2.3 对象定义 1) 父接口是IUnknown接口 2) 在对象内添加函数,函数定义必须 是返回 HRESULT. HRESULT是32位整数,返回函数是否 执行成功,需要使用 SUCCESSED和 FAILED宏来判断返回值.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值