杨老师的个人专栏地址:http://www.vckbase.com/vckbase/columnist/yangfeng/,敝人在此极力推荐,想学COM的朋友们千万别错过了这绝好的入门资料哦~
1,GUID,UUID,CLSID,IID,REFCLSID:
typedef
struct
_GUID {
DWORD Data1;
//
随机数
WORD Data2;
//
和时间相关
WORD Data3;
//
和时间相关
BYTE Data4[
8
];
//
和网卡MAC相关
} GUID;
typedef GUID CLSID;
//
组件ID
typedef GUID IID;
//
接口ID
#define
REFCLSID const CLSID &
//
常见的声明和赋值方法
CLSID CLSID_Excel
=
{
0x00024500
,
0x0000
,
0x0000
,{
0xC0
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x46
}};
struct
__declspec(uuid(
"
00024500-0000-0000-C000-000000000046
"
)) CLSID_Excel;
class
DECLSPEC_UUID(
"
00024500-0000-0000-C000-000000000046
"
) CLSID_Excel;
//
注册表中的表示方法
{
00024500
-
0000
-
0000
-
C000
-
000000000046
}
如果使用开发环境编写组件程序,则IDE会自动帮你产生CLSID.可以手动写CLSID,但难以保证与其它CLSID不重复,在程序中可以使用CoCreateGuid来产生GUID,或者通过工具来产生.
ProgId(Program ID)&CLSID其实是一个概念的两种不同的表现形式.注册表子键 ProgID 和 VersionIndependentProgID 分别表示真正的 ProgID 和版本无关的 ProgID.
函数 | 功能说明 |
CLSIDFromProgID()、CLSIDFromProgIDEx() | 由 ProgID 得到 CLSID。没什么好说的,你自己都可以写,查注册表贝 |
ProgIDFromCLSID() | 由 CLSID 得到 ProgID,调用者使用完成后要释放 ProgID 的内存(注5) |
CoCreateGuid() | 随机生成一个 GUID |
IsEqualGUID()、IsEqualCLSID()、IsEqualIID() | 比较2个ID是否相等 |
StringFromCLSID()、StringFromGUID2()、StringFromIID() | 由 CLSID,IID 得到注册表中CLSID样式的字符串,注意释放内存 |
2,接口(interface)
QueryInterface函数被放在所有VTA(虚函数表)的开头,用来从一个表查找另一个表.
COM Interface structure
1、函数是通过 VTAB 虚函数表提供其地址, 从另一个角度来看,不管用什么语言开发,编译器产生的代码都能生成这个表。这样就实现了组件的“二进制特性”轻松实现了组件的跨语言要求。
2、假设有一个指针型变量保存着 VTAB 的首地址,则这个变量就叫“接口指针”(注6), 变量命名的时候,习惯上加上"I"开头。另外为了区分不同的接口,每个接口 也都要有一个名字,该名字就和 CLSID 一样,使用 GUID 方式,叫 IID。
3、接口一经发表,就不能再修改了。不然就会出现向前兼容的问题。这个性质叫“接口不变性”。
4、组件中必须有3个函数,QueryInterface、AddRef、Release,它们3个函数也组成一个接口,叫"IUnknown"。任何接口都继承自IUnknown.
5、在任何接口上,调用表中的第一个函数,其实就是调用 QueryInterface()函数,就得到你想要的另外一个接口指针。这个性质叫“接口的传递性”
6、通过类型库实现接口声明的独立性.
转载于:https://www.cnblogs.com/cmleung/archive/2009/10/21/1587245.html
原文链接:https://blog.csdn.net/weixin_30342827/article/details/97713842
本站声明:网站内容来源于网络,如有侵权,请联系我们,我们将及时处理。
还没有人抢沙发呢~