来新公司学习接手新项目,拿到代码打开解决方案看到里面居然有40几个工程,有点吃惊。具体看代码也有不少以前没见过的写法,上了几天火。git
有件事就没太搞明白,按照文档的说法上层不少软件都要调用IO服务器,但看程序安装目录,IO服务器实际上是一个exe程序,按照我以前的印象,能被别的程序调用的也得是动态库、静态库或者服务。实在想不通exe程序怎么做为接口被别的程序调用的。程序员
结果昨天研究了一天,想通了,这个IO服务器其实就是COM组件。github
按照网上的说法:COM component(COM组件)是微软公司为了计算机工业的软件生产更加符合人类的行为方式开发的一种新的软件开发技术。在COM构架下,人们能够开发出各类各样的功能专注的组件,而后将它们按照须要组合起来,构成复杂的应用系统。由此带来的好处是多方面的:能够将系统中的组件用新的替换掉,以便随时进行系统的升级和定制;能够在多个应用系统中重复利用同一个组件;能够方便的将应用系统扩展到网络环境下;COM与语言,平台无关的特性使全部的程序员都可充分发挥本身的才智与专长编写组件模块。小程序
COM组件能够是dll或者exe或者服务的形式。服务器
按照这个思路,代码就看懂了很多,之因此解决方案里有那么多工程,也不过是由于划分了不少动态库和COM组件。网络
又花了些时间,写了个小程序来实现最简单的exe形式COM组件的生成与调用,以下:分布式
首先创建一个ALT工程:函数
在类视图里,为工程添加ALT的类,和接口:学习
这里定义了类,和对应的接口(Interface),注意ProgID要写,待会程序调用com接口时,要经过ProgID找com组件字体
以后项目目录以下,在.idl文件里有com接口(interface),里面还定义了com组件的id等等不赘述了,实现类在ATLTest.cpp里,其对应关系都是vs自动搭建的。
接下来仍是在类视图里具体添加方法(接口和实现):
方法内部写程序,逻辑是两数求和:
STDMETHODIMP CCATLTest::ATLTestFunc0(SHORT num1, SHORT num2, SCODE* pRetNum) { *pRetNum = num1 + num2; return S_OK; }
而后编译会出错,那是由于执行com组件注册命令时候,缺少管理员权限,
从新启动vs,以管理员权限运行便可。
接下来建一个mfc项目,这不是今天主题就不赘述了,
在界面上简单填个按钮和输入框,写个两数求和的图形界面demo,
具体的求和的方法要调用com组件。
mfc项目里添加com接口,在类向导里选择添加类,选atl,选TypeLib中的MFC类:
以后能够选取前面定义的Lib:
加入COM接口文件后,就能够调用了,注意我下面的写法:
void CATLMfcClientDlg::OnBnClickedGetRetButton() { CoInitialize(NULL); CATLTest myCom; if (!myCom.CreateDispatch(_T("ATLTest.math.1"))) { MessageBox(L"组件注册失败"); return; } CString strNum1,strNum2; // 获取用户输入的数字 this->numInput1.GetWindowTextW(strNum1); this->numInput2.GetWindowTextW(strNum2); // 调用COM接口,两数求和 short ret = myCom.ATLTestFunc0(_wtoi(strNum1),_wtoi(strNum2)); WCHAR buf[50]; _itow(ret,buf,10); // 显示结果 this->numRet.SetWindowTextW(buf); CoUninitialize(); return; }
运行效果:
上面有说的简略的地方,具体能够看我上传git的源码:
https://github.com/SonnAdolf/MyAtlExeComDemo
额外内容:
动态连接库和COM组件的区别
1动态连接库的表现形式只能是dll[变态该名的除外], COM组件的表现形式能够是dll也能够是exe。
注:其实字体、驱动等也算是动态连接库的一种,这里略去...
2 动态连接库的生成和编译器及系统相关,在Windows/Linux下系统,须要分别编译才能使用。
COM组件是二进制编码,在Windows和Linux下能够直接使用,不须要从新编译。
3 COM组件是按照COM规范实现的dll或者exe;动态连接库是一个能够导出函数的函数集合。
4 动态连接库只能在本机被调用,COM组件支持分布式使用。