COM的历史与ATL
下面的示例程序来自:《COM+技术内幕》
所得:
组件的目标:
- 语言无关(发布的时候必须是二进制的,编译链接好的),这样才能在市场中存活下来,使得语言的流行不会冲击应用程序。
- 升级不影响客户的正常使用
- 远程组件与位置无关,必须像本地组件一样使用
- 新老版本兼容:
组件的需求:
- 动态链接:如果不能动态链接,就无法升级,就不能在用户使用的过程中将程序替换掉。
- 信息封装:只要接口不变化,双方组件发生了变化都不会影响对方。反之,只要接口变了,另一方为了适应必须要做出被动的调整。
接口的设计:
- 接口的设计者要有预测未来的能力,这对大多数人来说都是很困难的。
各种接口:
- DLL接口:导出函数
- C++接口:抽象基类的成员函数,变为COM接口需要继承IUnknown接口
- COM接口:接口就是一切
interface接口:
interface接口在ObjBase.h中被定义如下:
#define __STRUCT__ struct
#define interface __STRUCT__
com开发示例程序
主要为了展示最基本的com开发示例程序,略见一斑。
工程百度云下载:http://pan.baidu.com/s/1qYSrXtM
源代码:
#include <iostream>
using namespace std;
#include <ObjBase.h>
void trace(const char* pMsg)
{
cout<< pMsg<<endl;
}
interface IX
{
virtual void __stdcall Fx1(void) = 0;
virtual void __stdcall Fx2(void) = 0;
};
interface IY
{
virtual void __stdcall Fy1(void) = 0;
virtual void __stdcall Fy2(void) = 0;
};
class CA : public IX , public IY
{
public:
virtual void __stdcall Fx1() { cout<<"CA::Fx1()"<<endl;}
virtual void __stdcall Fx2() { cout<<"CA::Fx2()"<<endl;}
virtual void __stdcall Fy1() { cout<<"CA::Fy1()"<<endl;}
virtual void __stdcall Fy2() { cout<<"CA::Fy2()"<<endl;}
};
int main()
{
trace("client: create an instance of the component.");
CA* pA = new CA;
trace("client: use the IX interface.");
IX* pIX = pA;
pIX->Fx1();
pIX->Fx2();
trace("client: use the IY interface.");
IY* pIY = pA;
pIY->Fy1();
pIY->Fy2();
trace("client: delete the component.");
delete pA;
}
输出: