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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161
