COM程序的简单实现(COM技术内幕笔记之一)
这是今天在读《COM技术内幕》这本书时模拟COM而写的一段代码,包括了基本的接口(IX,IY), 组件的实现(CA),以及对组件的调用。
这段代码知识点涵盖了此书的前四章,还没有实现的是,把组件,接口放到动态链接库去实现。 这本书的第五章就讲到了动态链接库库对COM组件的封装。先在此把前面的代码总结,并保存下来。
1#include "StdAfx.h"
2#include <iostream.h>
3#include <objbase.h>
4
5
6void trace(const char* msg){ cout<<msg<<endl;}
7
8//Interfaces start
9interface IX:IUnknown
10{
11 virtual void __stdcall Fx() = 0;
12};
13
14interface IY:IUnknown
15{
16 virtual void __stdcall Fy() = 0;
17};
18
19interface IZ:IUnknown
20{
21 virtual void __stdcall Fz() = 0;
22};
23
24//Forward references for GUIDs
25extern const IID IID_IX;
26extern const IID IID_IY;
27extern const IID IID_IZ;
28//Interface end
29
30
31
32//component start
33class 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;}
42public:
43 CA();
44 ~CA(){trace("CA: Destory Self");}
45};
46
47
48CA::CA()
49{
50 trace("CA: Constrator Self");
51 m_cRef = 0;
52}
53
54HRESULT __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
81ULONG __stdcall CA::AddRef()
82{
83 InterlockedIncrement(&m_cRef);
84 cout<<"CA AddRef -- Ref:"<<m_cRef<<endl;
85 return m_cRef;
86}
87
88ULONG __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
100IUnknown* CreateInstance()
101{
102 IUnknown* pI = static_cast<IX*>(new CA);
103 pI->AddRef();
104 return pI;
105}
106
107// {05464095-EC3A-45b3-8E0C-D1793FBDF13D}
108static const IID IID_IX =
109{ 0x5464095, 0xec3a, 0x45b3, { 0x8e, 0xc, 0xd1, 0x79, 0x3f, 0xbd, 0xf1, 0x3d } };
110
111// {39696224-3AE3-4b46-B056-99359CAC6CA9}
112static const IID IID_IY =
113{ 0x39696224, 0x3ae3, 0x4b46, { 0xb0, 0x56, 0x99, 0x35, 0x9c, 0xac, 0x6c, 0xa9 } };
114
115// {6684A06D-64B8-46f3-9988-CDC119E18165}
116static 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
123int 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
2#include <iostream.h>
3#include <objbase.h>
4
5
6void trace(const char* msg){ cout<<msg<<endl;}
7
8//Interfaces start
9interface IX:IUnknown
10{
11 virtual void __stdcall Fx() = 0;
12};
13
14interface IY:IUnknown
15{
16 virtual void __stdcall Fy() = 0;
17};
18
19interface IZ:IUnknown
20{
21 virtual void __stdcall Fz() = 0;
22};
23
24//Forward references for GUIDs
25extern const IID IID_IX;
26extern const IID IID_IY;
27extern const IID IID_IZ;
28//Interface end
29
30
31
32//component start
33class 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;}
42public:
43 CA();
44 ~CA(){trace("CA: Destory Self");}
45};
46
47
48CA::CA()
49{
50 trace("CA: Constrator Self");
51 m_cRef = 0;
52}
53
54HRESULT __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
81ULONG __stdcall CA::AddRef()
82{
83 InterlockedIncrement(&m_cRef);
84 cout<<"CA AddRef -- Ref:"<<m_cRef<<endl;
85 return m_cRef;
86}
87
88ULONG __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
100IUnknown* CreateInstance()
101{
102 IUnknown* pI = static_cast<IX*>(new CA);
103 pI->AddRef();
104 return pI;
105}
106
107// {05464095-EC3A-45b3-8E0C-D1793FBDF13D}
108static const IID IID_IX =
109{ 0x5464095, 0xec3a, 0x45b3, { 0x8e, 0xc, 0xd1, 0x79, 0x3f, 0xbd, 0xf1, 0x3d } };
110
111// {39696224-3AE3-4b46-B056-99359CAC6CA9}
112static const IID IID_IY =
113{ 0x39696224, 0x3ae3, 0x4b46, { 0xb0, 0x56, 0x99, 0x35, 0x9c, 0xac, 0x6c, 0xa9 } };
114
115// {6684A06D-64B8-46f3-9988-CDC119E18165}
116static 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
123int 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