COM程序的简单实现(COM技术内幕笔记之一)
这是今天在读《COM技术内幕》这本书时模拟COM而写的一段代码,包括了基本的接口(IX,IY), 组件的实现(CA),以及对组件的调用。
这段代码知识点涵盖了此书的前四章,还没有实现的是,把组件,接口放到动态链接库去实现。 这本书的第五章就讲到了动态链接库库对COM组件的封装。先在此把前面的代码总结,并保存下来。
1
#include "StdAfx.h"
2
#include <iostream.h>
3
#include <objbase.h>
4
5
6
void trace(const char* msg){ cout<<msg<<endl;}
7
8
//Interfaces start
9
interface IX:IUnknown
10
{
11
virtual void __stdcall Fx() = 0;
12
};
13
14
interface IY:IUnknown
15
{
16
virtual void __stdcall Fy() = 0;
17
};
18
19
interface IZ:IUnknown
20
{
21
virtual void __stdcall Fz() = 0;
22
};
23
24
//Forward references for GUIDs
25
extern const IID IID_IX;
26
extern const IID IID_IY;
27
extern const IID IID_IZ;
28
//Interface end
29
30
31
32
//component start
33
class CA:public IX,public IY
34
{
35
LONG m_cRef;
36
virtual HRESULT __stdcall QueryInterface(const IID& iid,void** ppv);
37
virtual ULONG __stdcall AddRef();
38
virtual ULONG __stdcall Release();
39
40
virtual void __stdcall Fx(){cout<<"Fx function"<<endl;}
41
virtual void __stdcall Fy(){cout<<"Fy function"<<endl;}
42
public:
43
CA();
44
~CA(){trace("CA: Destory Self");}
45
};
46
47
48
CA::CA()
49
{
50
trace("CA: Constrator Self");
51
m_cRef = 0;
52
}
53
54
HRESULT __stdcall CA::QueryInterface(const IID &iid,void **ppv)
55
{
56
if(iid == IID_IUnknown)
57
{
58
trace("QueryInterface:Return pointer to IUnknown");
59
*ppv = static_cast<IX*>(this);
60
}
61
else if(iid == IID_IX)
62
{
63
trace("QueryInterface:Return pointer to IX");
64
*ppv = static_cast<IX*>(this);
65
}
66
else if(iid == IID_IY)
67
{
68
trace("QueryInterface:Return pointer to IX");
69
*ppv = static_cast<IY*>(this);
70
}
71
else
72
{
73
trace("QueryInteface Interface not supported");
74
*ppv = NULL;
75
return E_NOINTERFACE;
76
}
77
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
78
return S_OK;
79
}
80
81
ULONG __stdcall CA::AddRef()
82
{
83
InterlockedIncrement(&m_cRef);
84
cout<<"CA AddRef -- Ref:"<<m_cRef<<endl;
85
return m_cRef;
86
}
87
88
ULONG __stdcall CA::Release()
89
{
90
91
if(InterlockedDecrement(&m_cRef)==0)
92
{
93
delete this;
94
return 0;
95
}
96
cout<<"CA ReleaseRef -- Ref:"<<m_cRef<<endl;
97
return m_cRef;
98
}
99
100
IUnknown* CreateInstance()
101
{
102
IUnknown* pI = static_cast<IX*>(new CA);
103
pI->AddRef();
104
return pI;
105
}
106
107
// {05464095-EC3A-45b3-8E0C-D1793FBDF13D}
108
static const IID IID_IX =
109
{ 0x5464095, 0xec3a, 0x45b3, { 0x8e, 0xc, 0xd1, 0x79, 0x3f, 0xbd, 0xf1, 0x3d } };
110
111
// {39696224-3AE3-4b46-B056-99359CAC6CA9}
112
static const IID IID_IY =
113
{ 0x39696224, 0x3ae3, 0x4b46, { 0xb0, 0x56, 0x99, 0x35, 0x9c, 0xac, 0x6c, 0xa9 } };
114
115
// {6684A06D-64B8-46f3-9988-CDC119E18165}
116
static const IID IID_IZ =
117
{ 0x6684a06d, 0x64b8, 0x46f3, { 0x99, 0x88, 0xcd, 0xc1, 0x19, 0xe1, 0x81, 0x65 } };
118
//component end
119
120
121
122
//client start
123
int main(int argc, char* argv[])
124
{
125
HRESULT hr;
126
trace("Client: Get an IUnknown pointer");
127
IUnknown* pIUnknown = CreateInstance();
128
IX* pIx = NULL;
129
trace("Client: Get Interface IX");
130
hr = pIUnknown->QueryInterface(IID_IX,(void**)&pIx);
131
if(SUCCEEDED(hr))
132
{
133
trace("Client: Succeed Get Interface IX");
134
pIx->Fx();
135
}
136
137
IY* pIY = NULL;
138
hr = pIUnknown->QueryInterface(IID_IY,(void**)&pIY);
139
pIUnknown->Release();
140
if(SUCCEEDED(hr))
141
{
142
trace("Client: Succeed GetInterface IY");
143
pIY->Fy();
144
pIY->Release();
145
}
146
147
//Query IY from IX
148
IY* pIYfromIX = NULL;
149
hr = pIx->QueryInterface(IID_IY,(void**)&pIYfromIX);
150
if(SUCCEEDED(hr))
151
{
152
trace("Client: Succeed GetInterfae IY from pIX");
153
pIYfromIX->Fy();
154
pIYfromIX->Release();
155
}
156
pIx->Release();
157
//delete component
158
// delete pIUnknown;
159
return 0;
160
}
161
//client end
#include "StdAfx.h"2
#include <iostream.h>3
#include <objbase.h>4

5

6
void trace(const char* msg){ cout<<msg<<endl;}7

8
//Interfaces start9
interface IX:IUnknown10
{11
virtual void __stdcall Fx() = 0;12
};13

14
interface IY:IUnknown15
{16
virtual void __stdcall Fy() = 0;17
};18

19
interface IZ:IUnknown20
{21
virtual void __stdcall Fz() = 0;22
};23

24
//Forward references for GUIDs25
extern const IID IID_IX;26
extern const IID IID_IY;27
extern const IID IID_IZ;28
//Interface end29

30

31

32
//component start33
class CA:public IX,public IY34
{35
LONG m_cRef;36
virtual HRESULT __stdcall QueryInterface(const IID& iid,void** ppv);37
virtual ULONG __stdcall AddRef();38
virtual ULONG __stdcall Release();39

40
virtual void __stdcall Fx(){cout<<"Fx function"<<endl;}41
virtual void __stdcall Fy(){cout<<"Fy function"<<endl;}42
public:43
CA();44
~CA(){trace("CA: Destory Self");}45
};46

47

48
CA::CA()49
{50
trace("CA: Constrator Self");51
m_cRef = 0;52
}53

54
HRESULT __stdcall CA::QueryInterface(const IID &iid,void **ppv)55
{56
if(iid == IID_IUnknown)57
{58
trace("QueryInterface:Return pointer to IUnknown");59
*ppv = static_cast<IX*>(this);60
}61
else if(iid == IID_IX)62
{63
trace("QueryInterface:Return pointer to IX");64
*ppv = static_cast<IX*>(this);65
}66
else if(iid == IID_IY)67
{68
trace("QueryInterface:Return pointer to IX");69
*ppv = static_cast<IY*>(this);70
}71
else72
{73
trace("QueryInteface Interface not supported");74
*ppv = NULL;75
return E_NOINTERFACE;76
}77
reinterpret_cast<IUnknown*>(*ppv)->AddRef();78
return S_OK;79
}80

81
ULONG __stdcall CA::AddRef()82
{83
InterlockedIncrement(&m_cRef);84
cout<<"CA AddRef -- Ref:"<<m_cRef<<endl;85
return m_cRef;86
}87

88
ULONG __stdcall CA::Release()89
{90
91
if(InterlockedDecrement(&m_cRef)==0)92
{93
delete this;94
return 0;95
}96
cout<<"CA ReleaseRef -- Ref:"<<m_cRef<<endl;97
return m_cRef;98
}99

100
IUnknown* CreateInstance()101
{102
IUnknown* pI = static_cast<IX*>(new CA);103
pI->AddRef();104
return pI;105
}106

107
// {05464095-EC3A-45b3-8E0C-D1793FBDF13D}108
static const IID IID_IX = 109
{ 0x5464095, 0xec3a, 0x45b3, { 0x8e, 0xc, 0xd1, 0x79, 0x3f, 0xbd, 0xf1, 0x3d } };110

111
// {39696224-3AE3-4b46-B056-99359CAC6CA9}112
static const IID IID_IY = 113
{ 0x39696224, 0x3ae3, 0x4b46, { 0xb0, 0x56, 0x99, 0x35, 0x9c, 0xac, 0x6c, 0xa9 } };114

115
// {6684A06D-64B8-46f3-9988-CDC119E18165}116
static const IID IID_IZ = 117
{ 0x6684a06d, 0x64b8, 0x46f3, { 0x99, 0x88, 0xcd, 0xc1, 0x19, 0xe1, 0x81, 0x65 } };118
//component end119

120

121

122
//client start123
int main(int argc, char* argv[])124
{125
HRESULT hr;126
trace("Client: Get an IUnknown pointer");127
IUnknown* pIUnknown = CreateInstance();128
IX* pIx = NULL;129
trace("Client: Get Interface IX");130
hr = pIUnknown->QueryInterface(IID_IX,(void**)&pIx);131
if(SUCCEEDED(hr))132
{133
trace("Client: Succeed Get Interface IX");134
pIx->Fx();135
}136

137
IY* pIY = NULL;138
hr = pIUnknown->QueryInterface(IID_IY,(void**)&pIY);139
pIUnknown->Release();140
if(SUCCEEDED(hr))141
{142
trace("Client: Succeed GetInterface IY");143
pIY->Fy();144
pIY->Release();145
}146

147
//Query IY from IX148
IY* pIYfromIX = NULL;149
hr = pIx->QueryInterface(IID_IY,(void**)&pIYfromIX);150
if(SUCCEEDED(hr))151
{152
trace("Client: Succeed GetInterfae IY from pIX");153
pIYfromIX->Fy();154
pIYfromIX->Release();155
}156
pIx->Release();157
//delete component158
// delete pIUnknown;159
return 0;160
}161
//client end


浙公网安备 33010602011771号