Kselax.ru

Hacker Kselax — the best hacker in the world

Menu
  • Блог
  • Контакты
  • wp plugin генератор
  • Русский
    • Русский
    • English
Menu

ATL пример создания COM объекта DLL

Posted on 2 августа, 2015 by admin

Как создать MFC COM смотрите тут.

И так рассмотрим как создается COM объект в ATL, ATL — это библиотека которая генерирует каркас для COM компонент и ActiveX элементов. В книгах пишут что с ее помощью создавать COM компоненты также легко как и создавать с помощью MFC приложения. Ну сейчас посмотрим. Начнем с создания приложения.

1. Создание приложения COM в MFC

Запускаем Visual Studio 2010, выбираем «Файл» -> «Проект…», в появившемся окошке вводим «Создать проект» выбираем «проект ATL» и даем имя ему «CAtlProc»

ATL create app

жмем «Ок», потом жмем «Далее» в появившемся окошке

ATL withard

ничего не меняем и жмем «Готово», мы будем создавать COM DLL. Мастер у нас сгенерирует следующий набор файлов

ATL workspace

2. Добавление COM класса

В общем добавим к нему наш COM класс, заходим в «Окно классов» кликаем правой клавишей мышки, в появившемся контекстном меню выбираем «Добавить» -> «Класс…», в появившемся окошке «Добавление класса» выбираем «Простой объект ATL»

ATL add class

жмем «Добавить», появится «Мастер простых объектов ATL», вводим имя нашего класса назовем его «CMyCOM», там где поле «Программный ИД» вводим строчку это будет у нас progID нашего приложения, введем туда «MY_COM» например.

ATL add class1

жмем кнопку «Далее» и еще раз «Далее» в появившемся окошке с настройками ничего не меняем жмем «Готово», у нас создастся два файла

CMyCOM.h »

 

1
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
// CMyCOM.h: объявление CCMyCOM
 
#pragma once
#include "resource.h"       // основные символы
 
 
 
#include "CAtlProc_i.h"
 
 
 
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Однопотоковые COM-объекты не поддерживаются должным образом платформой Windows CE, например платформами Windows Mobile, в которых не предусмотрена полная поддержка DCOM. Определите _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA, чтобы принудить ATL поддерживать создание однопотоковых COM-объектов и разрешить использование его реализаций однопотоковых COM-объектов. Для потоковой модели в вашем rgs-файле задано значение 'Free', поскольку это единственная потоковая модель, поддерживаемая не-DCOM платформами Windows CE."
#endif
 
using namespace ATL;
 
 
// CCMyCOM
 
class ATL_NO_VTABLE CCMyCOM :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CCMyCOM, &CLSID_CMyCOM>,
public IDispatchImpl<ICMyCOM, &IID_ICMyCOM, &LIBID_CAtlProcLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
CCMyCOM()
{
}
 
DECLARE_REGISTRY_RESOURCEID(IDR_CMYCOM)
 
 
BEGIN_COM_MAP(CCMyCOM)
COM_INTERFACE_ENTRY(ICMyCOM)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
 
 
 
DECLARE_PROTECT_FINAL_CONSTRUCT()
 
HRESULT FinalConstruct()
{
return S_OK;
}
 
void FinalRelease()
{
}
 
public:
 
 
 
};
 
OBJECT_ENTRY_AUTO(__uuidof(CMyCOM), CCMyCOM)

CMyCOM.cpp »

 

1
2
3
4
5
6
7
// CMyCOM.cpp: реализация CCMyCOM
 
#include "stdafx.h"
#include "CMyCOM.h"
 
 
// CCMyCOM

Создался обычный С++ класс. В IDL файл добавился наш класс

CAtlProc.idl »

1
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
// CAtlProc.idl: источник IDL для CAtlProc
//
 
// Этот файл будет обработан средством MIDL для
// создания библиотеки типов (CAtlProc.tlb) и кода маршалирования.
 
import "oaidl.idl";
import "ocidl.idl";
 
[
object,
uuid(6ED7E28C-095F-429B-9FFF-5C5BBC11D698),
dual,
nonextensible,
pointer_default(unique)
]
interface ICMyCOM : IDispatch{
};
[
uuid(4DD4A978-1D87-4FE5-929B-E0BDC8A8129A),
version(1.0),
]
library CAtlProcLib
{
importlib("stdole2.tlb");
[
uuid(26959F44-0BBF-4247-B24A-01A65D0F7DED)
]
coclass CMyCOM
{
[default] interface ICMyCOM;
};
};

Этот файл он сам заполняется.

3. Добавление интерфейсов к COM классу.

Добавим интерфейсы к нашему сгенерированному COM классу. Увы это мы должны сделать вручную, для этого нам нужно редактировать наш idl файл например добавим от такой код

1
2
3
4
5
6
7
8
9
10
11
12
[
object,
uuid(7D95CBC0-C33E-4E47-9405-AB4A01278878),
dual,
nonextensible,
pointer_default(unique)
]
interface IA : IDispatch
{
HRESULT P_A();
HRESULT Get_A([out,retval]long* nPosition);
};

Этот код добавит дуальный интерфейс IA, дуальный потому что он наследуется от IDispatch, также мы определили функции Get_A и P_A.

Добавим следующий код к файлу idl

1
2
3
4
5
6
7
8
[
object,
uuid(4D95CBC0-C33E-4E47-9405-AB4A01278878),
]
interface IB : IUnknown
{
HRESULT P_B();
};

добавит интерфейс IB с функцией P_B. и полностью приведем файл idl

CAtlProc.idl »

1
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
// CAtlProc.idl: источник IDL для CAtlProc
//
 
// Этот файл будет обработан средством MIDL для
// создания библиотеки типов (CAtlProc.tlb) и кода маршалирования.
 
import "oaidl.idl";
import "ocidl.idl";
 
[
object,
uuid(7D95CBC0-C33E-4E47-9405-AB4A01278878),
dual,
nonextensible,
pointer_default(unique)
]
interface IA : IDispatch
{
HRESULT P_A();
HRESULT Get_A([out,retval]long* nPosition);
};
[
object,
uuid(6ED7E28C-095F-429B-9FFF-5C5BBC11D698),
dual,
nonextensible,
pointer_default(unique)
]
interface ICMyCOM : IDispatch{
};
[
uuid(4DD4A978-1D87-4FE5-929B-E0BDC8A8129A),
version(1.0),
]
library CAtlProcLib
{
importlib("stdole2.tlb");
[
uuid(26959F44-0BBF-4247-B24A-01A65D0F7DED)
]
coclass CMyCOM
{
[default] interface ICMyCOM;
};
};
[
object,
uuid(4D95CBC0-C33E-4E47-9405-AB4A01278878),
]
interface IB : IUnknown
{
HRESULT P_B();
};

да чтобы создать GUID для интерфейсов, просто возьмите любой номер из этого же файла, скопируйте и измените несколько цифр например. Все дальше нажимаем F5 и нам пойдет компиляция, нам компилятор должен создать два файла из этого idl файла с определением интерфейсов и идентификаторами их. Жем F5 и у меня создалось 2 файла, вот их код

CAtlProc_i.h »

 

1
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
 
 
/* File created by MIDL compiler version 7.00.0555 */
/* at Sun Aug 02 08:08:51 2015
*/
/* Compiler settings for CAtlProc.idl:
    Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555
    protocol : dce , ms_ext, c_ext, robust
    error checks: allocation ref bounds_check enum stub_data
    VC __declspec() decoration level:
         __declspec(uuid()), __declspec(selectany), __declspec(novtable)
         DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING(  ) */
 
#pragma warning( disable: 4049 )  /* more than 64k source lines */
 
 
/* verify that the <rpcndr.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 475
#endif
 
#include "rpc.h"
#include "rpcndr.h"
 
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif // __RPCNDR_H_VERSION__
 
#ifndef COM_NO_WINDOWS_H
#include "windows.h"
#include "ole2.h"
#endif /*COM_NO_WINDOWS_H*/
 
#ifndef __CAtlProc_i_h__
#define __CAtlProc_i_h__
 
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
 
/* Forward Declarations */
 
#ifndef __IA_FWD_DEFINED__
#define __IA_FWD_DEFINED__
typedef interface IA IA;
#endif /* __IA_FWD_DEFINED__ */
 
 
#ifndef __ICMyCOM_FWD_DEFINED__
#define __ICMyCOM_FWD_DEFINED__
typedef interface ICMyCOM ICMyCOM;
#endif /* __ICMyCOM_FWD_DEFINED__ */
 
 
#ifndef __CMyCOM_FWD_DEFINED__
#define __CMyCOM_FWD_DEFINED__
 
#ifdef __cplusplus
typedef class CMyCOM CMyCOM;
#else
typedef struct CMyCOM CMyCOM;
#endif /* __cplusplus */
 
#endif /* __CMyCOM_FWD_DEFINED__ */
 
 
#ifndef __IB_FWD_DEFINED__
#define __IB_FWD_DEFINED__
typedef interface IB IB;
#endif /* __IB_FWD_DEFINED__ */
 
 
/* header files for imported files */
#include "oaidl.h"
#include "ocidl.h"
 
#ifdef __cplusplus
extern "C"{
#endif
 
 
#ifndef __IA_INTERFACE_DEFINED__
#define __IA_INTERFACE_DEFINED__
 
/* interface IA */
/* [unique][nonextensible][dual][uuid][object] */
 
 
EXTERN_C const IID IID_IA;
 
#if defined(__cplusplus) && !defined(CINTERFACE)
    
    MIDL_INTERFACE("7D95CBC0-C33E-4E47-9405-AB4A01278878")
    IA : public IDispatch
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE P_A( void) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE Get_A(
            /* [retval][out] */ long *nPosition) = 0;
        
    };
    
#else /* C style interface */
 
    typedef struct IAVtbl
    {
        BEGIN_INTERFACE
        
        HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
            IA * This,
            /* [in] */ REFIID riid,
            /* [annotation][iid_is][out] */
            __RPC__deref_out  void **ppvObject);
        
        ULONG ( STDMETHODCALLTYPE *AddRef )(
            IA * This);
        
        ULONG ( STDMETHODCALLTYPE *Release )(
            IA * This);
        
        HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
            IA * This,
            /* [out] */ UINT *pctinfo);
        
        HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
            IA * This,
            /* [in] */ UINT iTInfo,
            /* [in] */ LCID lcid,
            /* [out] */ ITypeInfo **ppTInfo);
        
        HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
            IA * This,
            /* [in] */ REFIID riid,
            /* [size_is][in] */ LPOLESTR *rgszNames,
            /* [range][in] */ UINT cNames,
            /* [in] */ LCID lcid,
            /* [size_is][out] */ DISPID *rgDispId);
        
        /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
            IA * This,
            /* [in] */ DISPID dispIdMember,
            /* [in] */ REFIID riid,
            /* [in] */ LCID lcid,
            /* [in] */ WORD wFlags,
            /* [out][in] */ DISPPARAMS *pDispParams,
            /* [out] */ VARIANT *pVarResult,
            /* [out] */ EXCEPINFO *pExcepInfo,
            /* [out] */ UINT *puArgErr);
        
        HRESULT ( STDMETHODCALLTYPE *P_A )(
            IA * This);
        
        HRESULT ( STDMETHODCALLTYPE *Get_A )(
            IA * This,
            /* [retval][out] */ long *nPosition);
        
        END_INTERFACE
    } IAVtbl;
 
    interface IA
    {
        CONST_VTBL struct IAVtbl *lpVtbl;
    };
 
    
 
#ifdef COBJMACROS
 
 
#define IA_QueryInterface(This,riid,ppvObject) \
    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
 
#define IA_AddRef(This) \
    ( (This)->lpVtbl -> AddRef(This) )
 
#define IA_Release(This) \
    ( (This)->lpVtbl -> Release(This) )
 
 
#define IA_GetTypeInfoCount(This,pctinfo) \
    ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) )
 
#define IA_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
    ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) )
 
#define IA_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
    ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) )
 
#define IA_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
    ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) )
 
 
#define IA_P_A(This) \
    ( (This)->lpVtbl -> P_A(This) )
 
#define IA_Get_A(This,nPosition) \
    ( (This)->lpVtbl -> Get_A(This,nPosition) )
 
#endif /* COBJMACROS */
 
 
#endif /* C style interface */
 
 
 
 
#endif /* __IA_INTERFACE_DEFINED__ */
 
 
#ifndef __ICMyCOM_INTERFACE_DEFINED__
#define __ICMyCOM_INTERFACE_DEFINED__
 
/* interface ICMyCOM */
/* [unique][nonextensible][dual][uuid][object] */
 
 
EXTERN_C const IID IID_ICMyCOM;
 
#if defined(__cplusplus) && !defined(CINTERFACE)
    
    MIDL_INTERFACE("6ED7E28C-095F-429B-9FFF-5C5BBC11D698")
    ICMyCOM : public IDispatch
    {
    public:
    };
    
#else /* C style interface */
 
    typedef struct ICMyCOMVtbl
    {
        BEGIN_INTERFACE
        
        HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
            ICMyCOM * This,
            /* [in] */ REFIID riid,
            /* [annotation][iid_is][out] */
            __RPC__deref_out  void **ppvObject);
        
        ULONG ( STDMETHODCALLTYPE *AddRef )(
            ICMyCOM * This);
        
        ULONG ( STDMETHODCALLTYPE *Release )(
            ICMyCOM * This);
        
        HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
            ICMyCOM * This,
            /* [out] */ UINT *pctinfo);
        
        HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
            ICMyCOM * This,
            /* [in] */ UINT iTInfo,
            /* [in] */ LCID lcid,
            /* [out] */ ITypeInfo **ppTInfo);
        
        HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
            ICMyCOM * This,
            /* [in] */ REFIID riid,
            /* [size_is][in] */ LPOLESTR *rgszNames,
            /* [range][in] */ UINT cNames,
            /* [in] */ LCID lcid,
            /* [size_is][out] */ DISPID *rgDispId);
        
        /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
            ICMyCOM * This,
            /* [in] */ DISPID dispIdMember,
            /* [in] */ REFIID riid,
            /* [in] */ LCID lcid,
            /* [in] */ WORD wFlags,
            /* [out][in] */ DISPPARAMS *pDispParams,
            /* [out] */ VARIANT *pVarResult,
            /* [out] */ EXCEPINFO *pExcepInfo,
            /* [out] */ UINT *puArgErr);
        
        END_INTERFACE
    } ICMyCOMVtbl;
 
    interface ICMyCOM
    {
        CONST_VTBL struct ICMyCOMVtbl *lpVtbl;
    };
 
    
 
#ifdef COBJMACROS
 
 
#define ICMyCOM_QueryInterface(This,riid,ppvObject) \
    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
 
#define ICMyCOM_AddRef(This) \
    ( (This)->lpVtbl -> AddRef(This) )
 
#define ICMyCOM_Release(This) \
    ( (This)->lpVtbl -> Release(This) )
 
 
#define ICMyCOM_GetTypeInfoCount(This,pctinfo) \
    ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) )
 
#define ICMyCOM_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
    ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) )
 
#define ICMyCOM_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
    ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) )
 
#define ICMyCOM_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
    ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) )
 
 
#endif /* COBJMACROS */
 
 
#endif /* C style interface */
 
 
 
 
#endif /* __ICMyCOM_INTERFACE_DEFINED__ */
 
 
 
#ifndef __CAtlProcLib_LIBRARY_DEFINED__
#define __CAtlProcLib_LIBRARY_DEFINED__
 
/* library CAtlProcLib */
/* [version][uuid] */
 
 
EXTERN_C const IID LIBID_CAtlProcLib;
 
EXTERN_C const CLSID CLSID_CMyCOM;
 
#ifdef __cplusplus
 
class DECLSPEC_UUID("26959F44-0BBF-4247-B24A-01A65D0F7DED")
CMyCOM;
#endif
#endif /* __CAtlProcLib_LIBRARY_DEFINED__ */
 
#ifndef __IB_INTERFACE_DEFINED__
#define __IB_INTERFACE_DEFINED__
 
/* interface IB */
/* [uuid][object] */
 
 
EXTERN_C const IID IID_IB;
 
#if defined(__cplusplus) && !defined(CINTERFACE)
    
    MIDL_INTERFACE("4D95CBC0-C33E-4E47-9405-AB4A01278878")
    IB : public IUnknown
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE P_B( void) = 0;
        
    };
    
#else /* C style interface */
 
    typedef struct IBVtbl
    {
        BEGIN_INTERFACE
        
        HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
            IB * This,
            /* [in] */ REFIID riid,
            /* [annotation][iid_is][out] */
            __RPC__deref_out  void **ppvObject);
        
        ULONG ( STDMETHODCALLTYPE *AddRef )(
            IB * This);
        
        ULONG ( STDMETHODCALLTYPE *Release )(
            IB * This);
        
        HRESULT ( STDMETHODCALLTYPE *P_B )(
            IB * This);
        
        END_INTERFACE
    } IBVtbl;
 
    interface IB
    {
        CONST_VTBL struct IBVtbl *lpVtbl;
    };
 
    
 
#ifdef COBJMACROS
 
 
#define IB_QueryInterface(This,riid,ppvObject) \
    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
 
#define IB_AddRef(This) \
    ( (This)->lpVtbl -> AddRef(This) )
 
#define IB_Release(This) \
    ( (This)->lpVtbl -> Release(This) )
 
 
#define IB_P_B(This) \
    ( (This)->lpVtbl -> P_B(This) )
 
#endif /* COBJMACROS */
 
 
#endif /* C style interface */
 
 
 
 
#endif /* __IB_INTERFACE_DEFINED__ */
 
 
/* Additional Prototypes for ALL interfaces */
 
/* end of Additional Prototypes */
 
#ifdef __cplusplus
}
#endif
 
#endif

CAtlProc_i.c »

 

1
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
/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */
 
/* link this file in with the server and any clients */
 
 
/* File created by MIDL compiler version 7.00.0555 */
/* at Sun Aug 02 08:08:51 2015
*/
/* Compiler settings for CAtlProc.idl:
    Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555
    protocol : dce , ms_ext, c_ext, robust
    error checks: allocation ref bounds_check enum stub_data
    VC __declspec() decoration level:
         __declspec(uuid()), __declspec(selectany), __declspec(novtable)
         DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING(  ) */
 
#pragma warning( disable: 4049 )  /* more than 64k source lines */
 
 
#ifdef __cplusplus
extern "C"{
#endif
 
 
#include <rpc.h>
#include <rpcndr.h>
 
#ifdef _MIDL_USE_GUIDDEF_
 
#ifndef INITGUID
#define INITGUID
#include <guiddef.h>
#undef INITGUID
#else
#include <guiddef.h>
#endif
 
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
        DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)
 
#else // !_MIDL_USE_GUIDDEF_
 
#ifndef __IID_DEFINED__
#define __IID_DEFINED__
 
typedef struct _IID
{
    unsigned long x;
    unsigned short s1;
    unsigned short s2;
    unsigned char  c[8];
} IID;
 
#endif // __IID_DEFINED__
 
#ifndef CLSID_DEFINED
#define CLSID_DEFINED
typedef IID CLSID;
#endif // CLSID_DEFINED
 
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
        const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
 
#endif !_MIDL_USE_GUIDDEF_
 
MIDL_DEFINE_GUID(IID, IID_IA,0x7D95CBC0,0xC33E,0x4E47,0x94,0x05,0xAB,0x4A,0x01,0x27,0x88,0x78);
 
 
MIDL_DEFINE_GUID(IID, IID_ICMyCOM,0x6ED7E28C,0x095F,0x429B,0x9F,0xFF,0x5C,0x5B,0xBC,0x11,0xD6,0x98);
 
 
MIDL_DEFINE_GUID(IID, LIBID_CAtlProcLib,0x4DD4A978,0x1D87,0x4FE5,0x92,0x9B,0xE0,0xBD,0xC8,0xA8,0x12,0x9A);
 
 
MIDL_DEFINE_GUID(CLSID, CLSID_CMyCOM,0x26959F44,0x0BBF,0x4247,0xB2,0x4A,0x01,0xA6,0x5D,0x0F,0x7D,0xED);
 
 
MIDL_DEFINE_GUID(IID, IID_IB,0x4D95CBC0,0xC33E,0x4E47,0x94,0x05,0xAB,0x4A,0x01,0x27,0x88,0x78);
 
#undef MIDL_DEFINE_GUID
 
#ifdef __cplusplus
}
#endif

файлы с интерфейсами созданы, теперь нам нужно добавить эти интерфейсы к самому классу, пока у нас только два интерфейса добавлено в карту интерфейсов

1
2
3
4
BEGIN_COM_MAP(CCMyCOM)
COM_INTERFACE_ENTRY(ICMyCOM)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

и от здесь третье третья строчка наследования добавляет дуальный интерфейс

1
2
3
4
5
class ATL_NO_VTABLE CCMyCOM :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CCMyCOM, &CLSID_CMyCOM>,
public IDispatchImpl<ICMyCOM, &IID_ICMyCOM, &LIBID_CAtlProcLib, /*wMajor =*/ 1, /*wMinor =*/ 0>//добавляется дуальный интерфейс
{

Добавим и мы наш дуальный интерфейс также, я просто приведу полностью код уже с добавленными интерфейсами и с наследованием.

1
2
3
4
5
6
7
class ATL_NO_VTABLE CCMyCOM :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CCMyCOM, &CLSID_CMyCOM>,
public IDispatchImpl<IA, &IID_ICMyCOM, &LIBID_CAtlProcLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,//добавляется дуальный интерфейс
public IDispatchImpl<ICMyCOM, &IID_IA, &LIBID_CAtlProcLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IB
{

видите мы просто сделали два наследования, похоже в ATL COM строится на наследовании.

1
2
3
4
5
6
BEGIN_COM_MAP(CCMyCOM)
COM_INTERFACE_ENTRY(ICMyCOM)
COM_INTERFACE_ENTRY(IA)
COM_INTERFACE_ENTRY(IB)
COM_INTERFACE_ENTRY2(IDispatch, ICMyCOM)
END_COM_MAP()

[warning]У нас получается в программе 2 дуальных интерфейса, чтобы при получении указателя на IDispatch у нас вызвался определенный интерфейс для этого существует специальный макрос COM_INTERFACE_ENTRY2 в котором вторым параметром указывается дуальный интерфейс который передается[/warning]

4. Добавление функций к нашему классу, перегрузка их

Заходим в окно классов, кликаем правой клавишей мышки по идентификатору интерфейса к которому мы хотим добавить функцию, например я хочу добавить функцию test к интерфейсу ICMyCOM, кликаю по нему правой клавишей, выбираю «Добавить»->»Добавить метод…», мы попадаем в окошко «Мастер добавления методов» в нем вводим такие настройки как на скрине ниже.

atl add mathod

там есть атрибуты, в означает что мы вводим в функцию данные, а из означает что из нее выводим, retval означает что что результат вызова метода можно присвоить переменной языка высокого уровня.[warning] Атрибуты «из» и «retval» доступны только когда в качестве параметра указан указатель. [/warning]. Жмем «Далее» и «Готово» и у нас добавилась функция к интерфейсу в файле idl.

Давайте таким же способом попробуем добавить функцию к интерфейсу IB, так же само кликаем правой клавишей мышки в «Окне классов» на идентификаторе IB, в контекстном меню выбираем «Добавить»->»Добавить метод…», попадаем в окошко «Мастер добавления методов» в нем вводим такие настройки

atl add class2

жмем «Готово», все определение функции добавилось к файлу idl. А также определения добавились к классу COM

Теперь нам нужно добавить в наш COM класс все переменные и заполнить его. Так как мы для интерфейсов IA и IB задали функции вручную, то их каркас не сгенерировался в классе COM CCMyCOM, поэтому его туда нужно добавить вручную.

В общем добавляем в класс CCMyCOM

1
2
3
public:
double m_a;
double m_b;

в конструкторе их инициализируем нулями.

Добавляем определения функций которых нет вручную

1
2
3
4
5
6
7
8
public:
//сами добавляем
STDMETHOD(P_A)();
STDMETHOD(Get_A)(LONG* nPosition);
STDMETHOD(P_B)();
//мастер добавил
STDMETHOD(test)(DOUBLE m_in, DOUBLE* m_out);
STDMETHOD(get_and_set)(DOUBLE m_in, DOUBLE* m_out);

Добавляем каркасы функций которых нету и заполняем все каркасы. Вот файл CMyCOM.cpp

CMyCOM.cpp »

1
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
// CMyCOM.cpp: реализация CCMyCOM
 
#include "stdafx.h"
#include "CMyCOM.h"
 
 
// CCMyCOM
 
 
STDMETHODIMP CCMyCOM::P_A()
{
// TODO: добавьте код реализации
ATLTRACE("CCMyCOM::P_A() m_a=%f\n",m_a);
 
return S_OK;
}
 
STDMETHODIMP CCMyCOM::Get_A(LONG* nPosition)
{
// TODO: добавьте код реализации
ATLTRACE("CCMyCOM::Get_A() m_a=%f\n",m_a);
*nPosition=m_a;//возврат
return S_OK;
}
 
STDMETHODIMP CCMyCOM::P_B()
{
// TODO: добавьте код реализации
ATLTRACE("CCMyCOM::P_B() m_b=%f\n",m_b);
 
return S_OK;
}
 
 
 
STDMETHODIMP CCMyCOM::test(DOUBLE m_in, DOUBLE* m_out)
{
// TODO: добавьте код реализации
m_a=m_in;
m_a*=3;
ATLTRACE("CCMyCOM::test() m_a=%f\n",m_a);
*m_out=m_a;//возврат m_a
 
return S_OK;
}
 
 
STDMETHODIMP CCMyCOM::get_and_set(DOUBLE m_in, DOUBLE* m_out)
{
// TODO: добавьте код реализации
m_a=m_in;
m_b=m_in;
ATLTRACE("CCMyCOM::test() m_a=%f m_b=%f\n",m_a,m_b);
*m_out=m_a+m_b;//возврат суммы
 
return S_OK;
}

На этом все, жмем F5 и у нас создается dll и сам файл регистрируется в реестре.

5. Тестируем приложение

Для того чтобы протестировать приложение просто создаем обычное приложение MFC «на основе диалоговых окон» и добавляем туда одну кнопку «start»

MFC start

 

в обработчик этой кнопки добавляем следующий код.

Показать »

1
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
void Ctest_COM2Dlg::OnBnClickedButton1()
{
// TODO: добавьте свой код обработчика уведомлений
CLSID clsid;//GUID
    LPCLASSFACTORY pClf=NULL; //IClassFactory
    LPUNKNOWN pUnk=NULL;
    IA* pIA=NULL;
    IB* pIB=NULL;
IDispatch* pIDis=NULL;
ICMyCOM* pICMyC=NULL;
  
    HRESULT hr;
hr=hr = ::CLSIDFromProgID(L"MY_COM.1", &clsid);
    if (!SUCCEEDED(hr)) {
        TRACE("unable to find Program ID -- error = %xn", hr);
        return;
    }
   if ((hr = ::CoGetClassObject(clsid, CLSCTX_INPROC_SERVER,
        NULL, IID_IClassFactory, (void **) &pClf)) != NOERROR) {;
        TRACE("unable to find CLSID -- error = %xn", hr);
        return;
    }
    pClf->CreateInstance(NULL, IID_IUnknown, (void**) &pUnk);
    pUnk->QueryInterface(IID_IA, (void**) &pIA); // All three
pIA->QueryInterface(IID_IB, (void**) &pIB); //  pointers
pIB->QueryInterface(IID_IDispatch, (void**) &pIDis);
pIDis->QueryInterface(IID_ICMyCOM, (void**) &pICMyC);
 
TRACE("main: pUnk = %p, pIA = %p, pIB = %p, pIDis= %p, pICMyC = %p\n", pUnk, pIA, pIB, pIDis, pICMyC );
 
pIA->P_A();
long pos=30;
pIA->Get_A(&pos);
TRACE("pos=%f\n",pos);
pIB->P_B();
double pos1;
pIB->get_and_set(30,&pos1);
TRACE("pos=%f\n",pos1);
pICMyC->test(20,&pos1);
TRACE("pos=%f\n",pos);
pClf->Release();
pUnk->Release();
pIA->Release();
pIB->Release();
pIDis->Release();
pICMyC->Release();
 
AfxMessageBox(L"Test succeeded. See Debug window for output.");
}

[warning]Так важный момент, в настройках класса мы задавали porgID «MY_COM» но он изменяется и посмотреть его можно в файле CMyCOM.rgs, вот его код

1
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
HKCR
{
MY_COM.1 = s 'CMyCOM Class'
{
CLSID = s '{26959F44-0BBF-4247-B24A-01A65D0F7DED}'
}
MY_COM = s 'CMyCOM Class'
{
CurVer = s 'MY_COM.1'
}
NoRemove CLSID
{
ForceRemove {26959F44-0BBF-4247-B24A-01A65D0F7DED} = s 'CMyCOM Class'
{
ProgID = s 'MY_COM.1'
VersionIndependentProgID = s 'MY_COM'
ForceRemove Programmable
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
TypeLib = s '{4DD4A978-1D87-4FE5-929B-E0BDC8A8129A}'
Version = s '1.0'
}
}
}

progID у нас из кода видно что MY_COM.1, а не MY_COM, в общем в этом файле смотрите progID, также в него добавляйте если вы забыли добавить при создании класса.[/warning]

К нашему проекту мы должны подключить следующие файлы которые были сгенерированы в ATL это файлы CAtlProc_i.c и CAtlProc_i.h, вот их код

CAtlProc_i.h »

 

1
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
 
 
/* File created by MIDL compiler version 7.00.0555 */
/* at Sun Aug 02 08:56:50 2015
*/
/* Compiler settings for CAtlProc.idl:
    Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555
    protocol : dce , ms_ext, c_ext, robust
    error checks: allocation ref bounds_check enum stub_data
    VC __declspec() decoration level:
         __declspec(uuid()), __declspec(selectany), __declspec(novtable)
         DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING(  ) */
 
#pragma warning( disable: 4049 )  /* more than 64k source lines */
 
 
/* verify that the <rpcndr.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 475
#endif
 
#include "rpc.h"
#include "rpcndr.h"
 
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif // __RPCNDR_H_VERSION__
 
#ifndef COM_NO_WINDOWS_H
#include "windows.h"
#include "ole2.h"
#endif /*COM_NO_WINDOWS_H*/
 
#ifndef __CAtlProc_i_h__
#define __CAtlProc_i_h__
 
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
 
/* Forward Declarations */
 
#ifndef __IA_FWD_DEFINED__
#define __IA_FWD_DEFINED__
typedef interface IA IA;
#endif /* __IA_FWD_DEFINED__ */
 
 
#ifndef __ICMyCOM_FWD_DEFINED__
#define __ICMyCOM_FWD_DEFINED__
typedef interface ICMyCOM ICMyCOM;
#endif /* __ICMyCOM_FWD_DEFINED__ */
 
 
#ifndef __CMyCOM_FWD_DEFINED__
#define __CMyCOM_FWD_DEFINED__
 
#ifdef __cplusplus
typedef class CMyCOM CMyCOM;
#else
typedef struct CMyCOM CMyCOM;
#endif /* __cplusplus */
 
#endif /* __CMyCOM_FWD_DEFINED__ */
 
 
#ifndef __IB_FWD_DEFINED__
#define __IB_FWD_DEFINED__
typedef interface IB IB;
#endif /* __IB_FWD_DEFINED__ */
 
 
/* header files for imported files */
#include "oaidl.h"
#include "ocidl.h"
 
#ifdef __cplusplus
extern "C"{
#endif
 
 
#ifndef __IA_INTERFACE_DEFINED__
#define __IA_INTERFACE_DEFINED__
 
/* interface IA */
/* [unique][nonextensible][dual][uuid][object] */
 
 
EXTERN_C const IID IID_IA;
 
#if defined(__cplusplus) && !defined(CINTERFACE)
    
    MIDL_INTERFACE("7D95CBC0-C33E-4E47-9405-AB4A01278878")
    IA : public IDispatch
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE P_A( void) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE Get_A(
            /* [retval][out] */ long *nPosition) = 0;
        
    };
    
#else /* C style interface */
 
    typedef struct IAVtbl
    {
        BEGIN_INTERFACE
        
        HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
            IA * This,
            /* [in] */ REFIID riid,
            /* [annotation][iid_is][out] */
            __RPC__deref_out  void **ppvObject);
        
        ULONG ( STDMETHODCALLTYPE *AddRef )(
            IA * This);
        
        ULONG ( STDMETHODCALLTYPE *Release )(
            IA * This);
        
        HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
            IA * This,
            /* [out] */ UINT *pctinfo);
        
        HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
            IA * This,
            /* [in] */ UINT iTInfo,
            /* [in] */ LCID lcid,
            /* [out] */ ITypeInfo **ppTInfo);
        
        HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
            IA * This,
            /* [in] */ REFIID riid,
            /* [size_is][in] */ LPOLESTR *rgszNames,
            /* [range][in] */ UINT cNames,
            /* [in] */ LCID lcid,
            /* [size_is][out] */ DISPID *rgDispId);
        
        /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
            IA * This,
            /* [in] */ DISPID dispIdMember,
            /* [in] */ REFIID riid,
            /* [in] */ LCID lcid,
            /* [in] */ WORD wFlags,
            /* [out][in] */ DISPPARAMS *pDispParams,
            /* [out] */ VARIANT *pVarResult,
            /* [out] */ EXCEPINFO *pExcepInfo,
            /* [out] */ UINT *puArgErr);
        
        HRESULT ( STDMETHODCALLTYPE *P_A )(
            IA * This);
        
        HRESULT ( STDMETHODCALLTYPE *Get_A )(
            IA * This,
            /* [retval][out] */ long *nPosition);
        
        END_INTERFACE
    } IAVtbl;
 
    interface IA
    {
        CONST_VTBL struct IAVtbl *lpVtbl;
    };
 
    
 
#ifdef COBJMACROS
 
 
#define IA_QueryInterface(This,riid,ppvObject) \
    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
 
#define IA_AddRef(This) \
    ( (This)->lpVtbl -> AddRef(This) )
 
#define IA_Release(This) \
    ( (This)->lpVtbl -> Release(This) )
 
 
#define IA_GetTypeInfoCount(This,pctinfo) \
    ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) )
 
#define IA_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
    ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) )
 
#define IA_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
    ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) )
 
#define IA_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
    ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) )
 
 
#define IA_P_A(This) \
    ( (This)->lpVtbl -> P_A(This) )
 
#define IA_Get_A(This,nPosition) \
    ( (This)->lpVtbl -> Get_A(This,nPosition) )
 
#endif /* COBJMACROS */
 
 
#endif /* C style interface */
 
 
 
 
#endif /* __IA_INTERFACE_DEFINED__ */
 
 
#ifndef __ICMyCOM_INTERFACE_DEFINED__
#define __ICMyCOM_INTERFACE_DEFINED__
 
/* interface ICMyCOM */
/* [unique][nonextensible][dual][uuid][object] */
 
 
EXTERN_C const IID IID_ICMyCOM;
 
#if defined(__cplusplus) && !defined(CINTERFACE)
    
    MIDL_INTERFACE("6ED7E28C-095F-429B-9FFF-5C5BBC11D698")
    ICMyCOM : public IDispatch
    {
    public:
        virtual /* [id] */ HRESULT STDMETHODCALLTYPE test(
            /* [in] */ DOUBLE m_in,
            /* [retval][out] */ DOUBLE *m_out) = 0;
        
    };
    
#else /* C style interface */
 
    typedef struct ICMyCOMVtbl
    {
        BEGIN_INTERFACE
        
        HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
            ICMyCOM * This,
            /* [in] */ REFIID riid,
            /* [annotation][iid_is][out] */
            __RPC__deref_out  void **ppvObject);
        
        ULONG ( STDMETHODCALLTYPE *AddRef )(
            ICMyCOM * This);
        
        ULONG ( STDMETHODCALLTYPE *Release )(
            ICMyCOM * This);
        
        HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
            ICMyCOM * This,
            /* [out] */ UINT *pctinfo);
        
        HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
            ICMyCOM * This,
            /* [in] */ UINT iTInfo,
            /* [in] */ LCID lcid,
            /* [out] */ ITypeInfo **ppTInfo);
        
        HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
            ICMyCOM * This,
            /* [in] */ REFIID riid,
            /* [size_is][in] */ LPOLESTR *rgszNames,
            /* [range][in] */ UINT cNames,
            /* [in] */ LCID lcid,
            /* [size_is][out] */ DISPID *rgDispId);
        
        /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
            ICMyCOM * This,
            /* [in] */ DISPID dispIdMember,
            /* [in] */ REFIID riid,
            /* [in] */ LCID lcid,
            /* [in] */ WORD wFlags,
            /* [out][in] */ DISPPARAMS *pDispParams,
            /* [out] */ VARIANT *pVarResult,
            /* [out] */ EXCEPINFO *pExcepInfo,
            /* [out] */ UINT *puArgErr);
        
        /* [id] */ HRESULT ( STDMETHODCALLTYPE *test )(
            ICMyCOM * This,
            /* [in] */ DOUBLE m_in,
            /* [retval][out] */ DOUBLE *m_out);
        
        END_INTERFACE
    } ICMyCOMVtbl;
 
    interface ICMyCOM
    {
        CONST_VTBL struct ICMyCOMVtbl *lpVtbl;
    };
 
    
 
#ifdef COBJMACROS
 
 
#define ICMyCOM_QueryInterface(This,riid,ppvObject) \
    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
 
#define ICMyCOM_AddRef(This) \
    ( (This)->lpVtbl -> AddRef(This) )
 
#define ICMyCOM_Release(This) \
    ( (This)->lpVtbl -> Release(This) )
 
 
#define ICMyCOM_GetTypeInfoCount(This,pctinfo) \
    ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) )
 
#define ICMyCOM_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
    ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) )
 
#define ICMyCOM_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
    ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) )
 
#define ICMyCOM_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
    ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) )
 
 
#define ICMyCOM_test(This,m_in,m_out) \
    ( (This)->lpVtbl -> test(This,m_in,m_out) )
 
#endif /* COBJMACROS */
 
 
#endif /* C style interface */
 
 
 
 
#endif /* __ICMyCOM_INTERFACE_DEFINED__ */
 
 
 
#ifndef __CAtlProcLib_LIBRARY_DEFINED__
#define __CAtlProcLib_LIBRARY_DEFINED__
 
/* library CAtlProcLib */
/* [version][uuid] */
 
 
EXTERN_C const IID LIBID_CAtlProcLib;
 
EXTERN_C const CLSID CLSID_CMyCOM;
 
#ifdef __cplusplus
 
class DECLSPEC_UUID("26959F44-0BBF-4247-B24A-01A65D0F7DED")
CMyCOM;
#endif
#endif /* __CAtlProcLib_LIBRARY_DEFINED__ */
 
#ifndef __IB_INTERFACE_DEFINED__
#define __IB_INTERFACE_DEFINED__
 
/* interface IB */
/* [uuid][object] */
 
 
EXTERN_C const IID IID_IB;
 
#if defined(__cplusplus) && !defined(CINTERFACE)
    
    MIDL_INTERFACE("4D95CBC0-C33E-4E47-9405-AB4A01278878")
    IB : public IUnknown
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE P_B( void) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE get_and_set(
            /* [in] */ DOUBLE m_in,
            /* [retval][out] */ DOUBLE *m_out) = 0;
        
    };
    
#else /* C style interface */
 
    typedef struct IBVtbl
    {
        BEGIN_INTERFACE
        
        HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
            IB * This,
            /* [in] */ REFIID riid,
            /* [annotation][iid_is][out] */
            __RPC__deref_out  void **ppvObject);
        
        ULONG ( STDMETHODCALLTYPE *AddRef )(
            IB * This);
        
        ULONG ( STDMETHODCALLTYPE *Release )(
            IB * This);
        
        HRESULT ( STDMETHODCALLTYPE *P_B )(
            IB * This);
        
        HRESULT ( STDMETHODCALLTYPE *get_and_set )(
            IB * This,
            /* [in] */ DOUBLE m_in,
            /* [retval][out] */ DOUBLE *m_out);
        
        END_INTERFACE
    } IBVtbl;
 
    interface IB
    {
        CONST_VTBL struct IBVtbl *lpVtbl;
    };
 
    
 
#ifdef COBJMACROS
 
 
#define IB_QueryInterface(This,riid,ppvObject) \
    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
 
#define IB_AddRef(This) \
    ( (This)->lpVtbl -> AddRef(This) )
 
#define IB_Release(This) \
    ( (This)->lpVtbl -> Release(This) )
 
 
#define IB_P_B(This) \
    ( (This)->lpVtbl -> P_B(This) )
 
#define IB_get_and_set(This,m_in,m_out) \
    ( (This)->lpVtbl -> get_and_set(This,m_in,m_out) )
 
#endif /* COBJMACROS */
 
 
#endif /* C style interface */
 
 
 
 
#endif /* __IB_INTERFACE_DEFINED__ */
 
 
/* Additional Prototypes for ALL interfaces */
 
/* end of Additional Prototypes */
 
#ifdef __cplusplus
}
#endif
 
#endif

CAtlProc_i.c »

 

1
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
/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */
 
/* link this file in with the server and any clients */
 
 
/* File created by MIDL compiler version 7.00.0555 */
/* at Sun Aug 02 08:56:50 2015
*/
/* Compiler settings for CAtlProc.idl:
    Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555
    protocol : dce , ms_ext, c_ext, robust
    error checks: allocation ref bounds_check enum stub_data
    VC __declspec() decoration level:
         __declspec(uuid()), __declspec(selectany), __declspec(novtable)
         DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING(  ) */
 
#pragma warning( disable: 4049 )  /* more than 64k source lines */
 
 
#ifdef __cplusplus
extern "C"{
#endif
 
 
#include <rpc.h>
#include <rpcndr.h>
 
#ifdef _MIDL_USE_GUIDDEF_
 
#ifndef INITGUID
#define INITGUID
#include <guiddef.h>
#undef INITGUID
#else
#include <guiddef.h>
#endif
 
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
        DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)
 
#else // !_MIDL_USE_GUIDDEF_
 
#ifndef __IID_DEFINED__
#define __IID_DEFINED__
 
typedef struct _IID
{
    unsigned long x;
    unsigned short s1;
    unsigned short s2;
    unsigned char  c[8];
} IID;
 
#endif // __IID_DEFINED__
 
#ifndef CLSID_DEFINED
#define CLSID_DEFINED
typedef IID CLSID;
#endif // CLSID_DEFINED
 
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
        const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
 
#endif !_MIDL_USE_GUIDDEF_
 
MIDL_DEFINE_GUID(IID, IID_IA,0x7D95CBC0,0xC33E,0x4E47,0x94,0x05,0xAB,0x4A,0x01,0x27,0x88,0x78);
 
 
MIDL_DEFINE_GUID(IID, IID_ICMyCOM,0x6ED7E28C,0x095F,0x429B,0x9F,0xFF,0x5C,0x5B,0xBC,0x11,0xD6,0x98);
 
 
MIDL_DEFINE_GUID(IID, LIBID_CAtlProcLib,0x4DD4A978,0x1D87,0x4FE5,0x92,0x9B,0xE0,0xBD,0xC8,0xA8,0x12,0x9A);
 
 
MIDL_DEFINE_GUID(CLSID, CLSID_CMyCOM,0x26959F44,0x0BBF,0x4247,0xB2,0x4A,0x01,0xA6,0x5D,0x0F,0x7D,0xED);
 
 
MIDL_DEFINE_GUID(IID, IID_IB,0x4D95CBC0,0xC33E,0x4E47,0x94,0x05,0xAB,0x4A,0x01,0x27,0x88,0x78);
 
#undef MIDL_DEFINE_GUID
 
#ifdef __cplusplus
}
#endif

файл CAtlProc_i.c нужно переименовать в CAtlProc_i.сpp и подключить вот так

1
2
#include "CAtlProc_i.h"
#include "CAtlProc_i.cpp"

в каждый из этих файлов в начале файла нужно добавить строчку

1
#include "stdafx.h"

Нажимаем F5, у нас компилируется и запускается программа, в программе нажимаем кнопку «start» и видим в отладчике следующее.

mfc debug

На это все.

[youtube]https://www.youtube.com/watch?v=aAXMwn9vbYI[/youtube]

 

Добавить комментарий Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Рубрики

  • C++ (293)
  • JavaScript (1)
  • linux (1)
  • MFC (39)
  • node.js (2)
  • React (3)
  • vBulletin (5)
  • Visual Studio (9)
  • wordpress (18)
  • Разное (29)

Метки

Ajax bootstrap CentOS CLI expressjs FormData GDlib google Invisible reCAPTCHA JWT media MFC php react-router-dom redux repository wordpress RTTI STL vBulletin vector Visual Studio WINAPI wordpress wp-plugins XMLHttpRequest Двоичное дерево Задачи С++ Игры С++ Исключения С++ О-большое Операторы_С++ Перегрузка операторов С++ Поиск С++ Потоки Проектирование_С++ С++ Типы_С++ Типы С++ Шаблоны С++ библиотеки локализация макросы С++ сортировка С++

Свежие комментарии

  • ExchiNuGs к записи Программка для заполнения форума на vBulletin 3.8.7
  • RA3PKJ к записи visual C++, создание диалоговых окон.
  • admin к записи Как удалить изображение из google
  • Shakanris к записи Программка для заполнения форума на vBulletin 3.8.7
  • костя к записи visual C++, создание диалоговых окон.
©2021 Kselax.ru Theme by ThemeGiant