COM学习
名词解释:
coclass: 是component object class的缩写,其中包含一个或者多个interface, coclass实现了这些接口;
COM object: 是coclass在内存中的实例
COM server: 是一个二进制文件(DLL 或者 Exe),其中包含一个或者多个coclass
Registration(注册): 创建注册表项,告诉Windows到哪里寻找COM server的过程
Guid: 每个interface或者coclass都有一个Guid, 还会看到uuid, 跟Guid是一回事
class ID, CLSID: 用来命名一个coclass;
interface ID, IID: 用来命名一个interface;
HRESULT: 一个整型数值,用来返回成功或者错误的代码
COM Library: 是操作系统的一部分, 当做与COM相关的事情的时候,与之交互
COM对象和标准Win32控件的区别
在使用标准win32控件的时候,首先要获得这个控件的句柄(handle, HWND),然后用sendmessage给它发送一个消息来操控它;同样,当控件要通知你什么消息或者给你传递一些数据时,它也要给你传递消息;
对于COM对象则不需要把消息传来传去.COM对象会给你一些特定的函数指针,你可以调用这些函数指针来操作COM对象;
COM对象和VTable
我们从一个简单的C的struct开始,我们定义一个struct:
struct IExample
{
DWORD count;
char buffer[80];
};
再用typedef来简化一下:
typedef struct
{
DWORD count;
char buffer[80];
} IEXample;
接下来,我们就可以使用这个struct了:
IExample* example;
example = (IExample*)GlobalAlloc(GMEM_FIXED, sizeof(IEXample));
example->count = 1;
example->buffer[0] = 0;
然后我们知道,struct中是可以包含函数指针的,假设我们现在有一个函数,这个函数有个字符指针的参数,返回值是long类型:
long SetString(char * str)
{
return (0);
}
这个时候我们就可以得到类似这样的代码:
#include <windows.h> typedef long SetStringPtr(char *); typedef struct { SetStringPtr* SetString; DWORD count; char buffer[80]; } IExample; long SetString(char *str) { return (0); } int _tmain(int argc, _TCHAR* argv[]) { IExample* example; example = (IExample*)GlobalAlloc(GMEM_FIXED, sizeof(IExample)); example->SetString = SetString; example->buffer[0] = 0; example->count = 1; long value = example->SetString("this is a test!"); return 0; }
但是,假如我们现在不想把函数指针直接存放在IExample内, 我们想要有一组函数指针.我们可以定义另一个struct,它的唯一的目的就是存放我们的函数指针,我们的代码就成了这个样子:
#include <windows.h> typedef long SetStringPtr(char *); typedef long GetStringPtr(char*, long); typedef struct { SetStringPtr* SetString; GetStringPtr* GetString; } IExampleVtbl; typedef struct { IExampleVtbl* lpVtbl; DWORD count; char buffer[80]; } IExample; long SetString(char *str) { return (0); } long GetString(char* str, long len) { return 0; } static IExampleVtbl IExample_Vtbl = {SetString, GetString}; int _tmain(int argc, _TCHAR* argv[]) { IExample* example; example = (IExample*)GlobalAlloc(GMEM_FIXED, sizeof(IExample)); example->lpVtbl = &IExample_Vtbl; example->buffer[0] = 0; example->count = 1; long value = example->lpVtbl->SetString("this is a test!"); return 0; }