您的位置:首页 > 其它

COM初步介绍

2007-08-03 15:45 183 查看
一、 COM的定义
微软的官方教材上是这样说的:COM是一个二进制对象互动的标准或模型。一个COM的重要特点是COM是已经预先编译过的。这就意味着COM是和语言无关的。我个人认为COM的定义是:COM是一种windows平台下二进制组件的复用技术。
二、COM的特性
COM和传统的编程方式相比,COM有以下诸多好处。
1、 语言独立性
COM允许多种语言对其进行调用。比如Visual Basic、Java、VB脚本等。
2、 本地透明性
客户可以不关心COM组件的位置。
3、 相对于第三方提供商的独立性
举个例子,可能某个数据库提供商升级了数据库的ODBC驱动。但是,您可能因为您基于旧版的ODBC驱动的应用程序太过复杂,而不愿意去为了新的ODBC驱动改动您的程序。
但是COM就没有这个问题。因为COM提供给客户的是接口。
新版接口可以和旧版接口保持一致,这样您就不用通过改动程序,而获得性能的提升。
4、 减少版本问题
因为,COM要求接口不变。虽然这样并没有完全解决版本问题,但是确实可以减少版本问题。
“既然COM技术这么好,那咱们就使用COM技术做开发吧。”,有人一定等不及了。下面我就介绍一下怎么使用COM组件。
调用COM组件
一、 预备知识
COM是怎么使用字符串的?
要说大家在用Visual C++进行基于MFC的编程时用得最多的class可能就是Cstring了。它确实很好用,我们在编程时处理字符串是常事。我们在COM组件里,也有class支持对字符串的操作。但是和以前有些不同,因为COM是独立于语言的。所以我们要求COM有极高的通用性。所以COM只支持unicode内码。如果您要问什么是unicode码,那么请您去查MSDN。
这是一个使用unicode的典型函数:
HRESULT CLSIDFromProgID(LPCOLESTR lpszProgID,
LPCLSID pclsid);
以下是经常使用的几个数据类型的声明:
typedef wchar_t WCHAR;
typedef WCHAR OLECHAR;
typedef const OLECHAR * LPCOLESTR;
其实很简单对不对?
对unicode字符串操作的类是CComBSTR.
还有一个模版类是_bstr_t
大家在MSDN里查以下这两个东东就会发现和Cstring没什么区别。
二、创建一个客户端调用COM
调用COM一共有5步:
1、 初始化COM库
2、 得到COM对象的CLSID
3、 创建一个COM对象的实例
4、 使用COM对象
5、
下边详细的说一下每步的工作。
一、初始化COM库。
初始化很简单,调用一下CoInitialize()函数就行。
CoInitialize()的返回值其实是long。但是这些数值被红定义了一下,其返回值变成了HRESULT。相应的微软又给我们提供了两个宏,用来判断返回值是否正确他们是SUCCEEDED、FAILED两个。
使用起来也很简单。
一段完整的初始化代码应该是:
InitInstance()
{
HRESULT hr;
hr = CoInitialize(NULL);
if (FAILED(hr))
return FALSE;
...
}
二、得到COM对象的CLSID。
对于CLSID大家有点陌生,这里详细说一下。大家都知道人的名字是容易重复的,但是人的身份证号就是唯一的。对于COM对像也一样。为了唯一的标识一个COM对象,微软提供了一中方法,就是给COM对象发全球唯一的号码。这个号码叫GUID
由128位二进制数组成。“有了它就不会重复了吗?”是的,确实能保证唯一。这个数很大,有个人说过这样一句话:“我不知道全球的细菌数总和,但是我知道2的128次方这个数肯定比细菌总和数多。”微软提供了一个叫guidgen.exe的工具用来生成GUID。这个工具在../Microsoft Visual Studio/Common/Tools下。但是这个数字太大了。我们一般的语言支持的数据类型没有这么大的,所以我们把这个128位二进制数放在一个结构体里。这个结构体就叫做CLSID。
我们可以通过一个函数来得到CLSID。
CLSID clsid;
HRESULT rc;
rc = CLSIDFromProgID(OLESTR("Simple.Object"),&clsid);
if (FAILED(rc))
{
MessageBox("Failure in call to CLSIDFromProgID");
return;
}
这样就OK了。简单吧?
三、创建一个COM对象的实例
其实,如果我们如果什么都不考虑的话我们可以使用new创建一个COM对象,但是COM是具有语言独立性的。并不是所有语言都支持new这个关键字。所以,我们需要调用一个专用函数叫CoCreateInstance()来创建COM对象。
参数情况请查阅MSDN
创建COM的代码如下:
IStream *pIStream;
rc = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER,
IID_IStream, (void**)&pIStream);
if (FAILED(rc))
{
MessageBox("Failure in call to CoCreateInstance");
return;
}
其中pIStream是指向接口的指针。
IID_Istream是一个GUID,每个接口也是有GUID的。因为接口名字也会重复^_^。
四、使用COM组件
这就比较简单了,COM的成员函数都是定义在接口里的,我们得到了指向接口的指针,那么调用方法不就手到擒来了吗?
pIStream->Write();
像这个样子就行了。
但是当客户端确定不再使用接口的方法了,请调用一下Release()方法。具体原因,下一次会讲。
五、反初始化COM库
反初始化COM库就像初始化一样简单。
调用一下这个函数就行了CoUninitialize()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: