Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π‘ΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ БОМ. Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 15

Автор Π”ΠΎΠ½Π°Π»ΡŒΠ΄ Бокс

extern "Π‘" const IID IID_IUnknown: interface IUnknown

{

virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv) = 0;

virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;

virtual ULONG STDMETHODCALLTYPE Release(void) = 0;

};


Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ SDK Π΄Π°ΡŽΡ‚ псСвдоним interface ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠΌΡƒ слову C++ struct, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ прСпроцСссор Π‘. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ интСрфСйсы Π² БОМ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Π½Π΅ ΠΊΠ°ΠΊ классы, Π° ΠΊΠ°ΠΊ структуры, Ρ‚ΠΎ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ интСрфСйса общСдоступными, ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово public Π½Π΅ трСбуСтся. Π§Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ для Ρ†Π΅Π»Π΅Π²ΠΎΠΉ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ БОМ-совмСстимыС стСковыС Ρ„Ρ€Π΅ΠΉΠΌΡ‹, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ макрос STDMETHODCALLTYPE. Если Ρ†Π΅Π»Π΅Π²Ρ‹ΠΌΠΈ ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ Win32, Ρ‚ΠΎ ΠΏΡ€ΠΈ использовании компилятора Microsoft C++ этот макрос раскрываСтся Π² _stdcall.

IUnknown Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ эквивалСнтСн IExtensibleObject. ΠœΠ΅Ρ‚ΠΎΠ΄ QueryInterface ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для динамичСского опрСдСлСния Ρ‚ΠΈΠΏΠ° ΠΈ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π΅Π½ Π‘++-ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρƒ dynamic_cast. ΠœΠ΅Ρ‚ΠΎΠ΄ AddRef ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для сообщСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ, Ρ‡Ρ‚ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ интСрфСйса Π΄ΡƒΠ±Π»ΠΈΡ€ΠΎΠ²Π°Π½. ΠœΠ΅Ρ‚ΠΎΠ΄ Release ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для сообщСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ, Ρ‡Ρ‚ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ интСрфСйса ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ΅Π½ ΠΈ всС рСсурсы, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π» ΠΎΡ‚ ΠΈΠΌΠ΅Π½ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹. Π“Π»Π°Π²Π½ΠΎΠ΅ Ρ€Π°Π·Π»ΠΈΡ‡ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρƒ IUnknown ΠΈ интСрфСйсом, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ Π³Π»Π°Π²Π΅, Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ IUnknown ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ GUID, Π° Π½Π΅ строки для ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Ρ‚ΠΈΠΏΠΎΠ² интСрфСйса Π½Π° этапС выполнСния.

IDL-ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ IUnknown ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π² Ρ„Π°ΠΉΠ»Π΅ unknwn.idl ΠΈΠ· Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ SDK, содСрТащСй Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹:


// unknwn.idl – system IDL file

// unknwn.idl – систСмный Ρ„Π°ΠΉΠ» IDL

[ local, object, uuid (00000000-0000-0000-C000-000000000046) ] interface IUnknown

{

HRESULT QueryInterface([in] REFIID riid, [out] void **ppv);

ULONG AddRef(void); ULONG Release(void);

}


Атрибут local подавляСт Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ сСтСвого ΠΊΠΎΠ΄Π° для этого интСрфСйса. Π­Ρ‚ΠΎΡ‚ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΌΡΠ³Ρ‡ΠΈΡ‚ΡŒ трСбования БОМ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ всС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ с ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Ρ… машин Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ HRESULT. Как Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Π³Π»Π°Π²Π°Ρ…, интСрфСйс IUnknown трактуСтся особым ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹ΠΌΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ. Π—Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ фактичСскиС, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠ΅ΡΡ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ IDL-описания интСрфСйсов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ содСрТатся Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°Ρ… SDK, Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ ΠΎΡ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ, Π΄Π°Π½Π½Ρ‹Ρ… Π² этой ΠΊΠ½ΠΈΠ³Π΅. ЀактичСскиС опрСдСлСния часто содСрТат Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ сСтСвого ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡ ΠΊ Π½Π°ΡˆΠ΅ΠΌΡƒ ΠΎΠ±ΡΡƒΠΆΠ΄Π΅Π½ΠΈΡŽ. Π’ случаС сомнСний ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ΡΡŒ Π·Π° ΠΏΠΎΠ»Π½Ρ‹ΠΌΠΈ опрСдСлСниями ΠΊ послСднСй вСрсии Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ² SDK.

Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ IUnknown являСтся Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΌ для всСх БОМ-интСрфСйсов. IUnknown – СдинствСнный интСрфСйс БОМ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ наслСдуСт ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ интСрфСйса. Π›ΡŽΠ±ΠΎΠΉ Π΄Ρ€ΡƒΠ³ΠΎΠΉ допустимый интСрфСйс БОМ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ прямым ΠΏΠΎΡ‚ΠΎΠΌΠΊΠΎΠΌ IUnknown ΠΈΠ»ΠΈ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ допустимого интСрфСйса БОМ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ, Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, Π΄ΠΎΠ»ΠΆΠ΅Π½ сам Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ прямо ΠΎΡ‚ IUnknown, ΠΈΠ»ΠΈ ΠΎΡ‚ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ допустимого интСрфСйса БОМ. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π½Π° Π΄Π²ΠΎΠΈΡ‡Π½ΠΎΠΌ ΡƒΡ€ΠΎΠ²Π½Π΅ всС интСрфСйсы БОМ ΡΠ²Π»ΡΡŽΡ‚ΡΡ указатСлями Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ vtbl, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‚ΡΡ с Ρ‚Ρ€Π΅Ρ… Ρ‚ΠΎΡ‡Π΅ΠΊ Π²Ρ…ΠΎΠ΄Π°: QueryInterface, AddRef ΠΈ Release. ВсС спСцифичСскиС для интСрфСйсов ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ‚ΠΎΡ‡ΠΊΠΈ Π²Ρ…ΠΎΠ΄Π° Π² vtbl, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΡΠ²Π»ΡΡŽΡ‚ΡΡ послС этих Ρ‚Ρ€Π΅Ρ… ΠΎΠ±Ρ‰ΠΈΡ… Ρ‚ΠΎΡ‡Π΅ΠΊ Π²Ρ…ΠΎΠ΄Π°.

Π§Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‚ интСрфСйса IDL, Π½ΡƒΠΆΠ½ΠΎ ΠΈΠ»ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ интСрфСйс Π² Ρ‚ΠΎΠΌ ΠΆΠ΅ IDL-Ρ„Π°ΠΉΠ»Π΅, ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Ρƒ import, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ внСшнСС IDL-ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ интСрфСйса явным Π² Π΄Π°Π½Π½ΠΎΠΉ области дСйствия:

// calculator.idl

[object, uuid(BDA4A270-A1BA-11dO-8C2C-0080C73925BA)]

interface ICalculator : IUnknown

{

import Β«unknwn.idlΒ»;

// bring in def. of IUnknown

// ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ IUnknown

HRESULT Clear(void);

HRESULT Add([in] long n);

HRESULT Sum([out, retval] long *pn);

}


ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ import ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΡΠ²Π»ΡΡ‚ΡŒΡΡ ΠΈΠ»ΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ опрСдСлСния интСрфСйса, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ здСсь, ΠΈΠ»ΠΈ ΠΏΡ€Π΅Π΄ΡˆΠ΅ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ описанию интСрфСйса Π² глобальной области дСйствия. Π’ любом ΠΈΠ· этих случаСв дСйствия ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° import ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹, ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ IDL-Ρ„Π°ΠΉΠ» Π±Π΅Π· всякого ΡƒΡ‰Π΅Ρ€Π±Π°. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ сгСнСрированный C/C++ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» Π±ΡƒΠ΄Π΅Ρ‚ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒ Π‘/Π‘++-вСрсии ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ IDL-Ρ„Π°ΠΉΠ»Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ наслСдованиС, ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ import ΠΈΠ· IDL-Ρ„Π°ΠΉΠ»Π° Π±ΡƒΠ΄Π΅Ρ‚ странслирован Π² ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ #include Π² Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Π‘/Π‘++-Ρ„Π°ΠΉΠ»Π΅:


// calculator.h – generated by MIDL

// calculator.h – Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ MIDL

// bring in def. of IUnknown

// Π²Π²ΠΎΠ΄ΠΈΠΌ опрСдСлСния IUnknown

#include Β«unknwn.hΒ»

extern "C" const IID IID_ICalculator;

interface ICalculator : public IUnknown

{

virtual HRESULT STDMETHODCALLTYPE Clear(void) = 0;

virtual HRESULT STDMETHODCALLTYPE Add(long n) = 0;

virtual HRESULT STDMETHODCALLTYPE Sum(long *pn) = 0;

}


ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€ MIDL Ρ‚Π°ΠΊΠΆΠ΅ создаст Π‘-Ρ„Π°ΠΉΠ», содСрТащий фактичСскиС опрСдСлСния всСх GUID, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ…ΡΡ Π² исходном IDL-Ρ„Π°ΠΉΠ»Π΅:


// calculator_i.с – generated by MIDL

const IID IID_ICalculator =

{ 0xBDA4A270, 0xA1BA, 0x11d0, { 0x8C, 0x2C, 

0x00, 0Ρ…80, 0Ρ…C7, 0Ρ…39, 0x25, 0xBA } };

ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ этот интСрфСйс, Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠ»ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ calculator_i.c ΠΊ своСму Ρ„Π°ΠΉΠ»Ρƒ сборки (makefile), ΠΈΠ»ΠΈ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ calculator_i.c Π² ΠΎΠ΄ΠΈΠ½ ΠΈΠ· исходных Ρ„Π°ΠΉΠ»ΠΎΠ² Π½Π° Π‘ ΠΈΠ»ΠΈ C++ с использованиСм прСпроцСссора Π‘. Если это Π½Π΅ сдСлано, Ρ‚ΠΎ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρƒ IID_ICalculator Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΎ памяти для Π΅Π³ΠΎ 128-Π±ΠΈΡ‚Π½ΠΎΠ³ΠΎ значСния ΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ скомпонован ΠΏΠΎ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅ Π½Π΅Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½Π½Ρ‹Ρ… Π²Π½Π΅ΡˆΠ½ΠΈΡ… ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠ².

БОМ Π½Π΅ Π½Π°ΠΊΠ»Π°Π΄Ρ‹Π²Π°Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ Π½Π° Π³Π»ΡƒΠ±ΠΈΠ½Ρƒ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ интСрфСйсов ΠΏΡ€ΠΈ условии, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΌ Π±Π°Π·ΠΎΠ²Ρ‹ΠΌ интСрфСйсом являСтся IUnknown. ΠΠΈΠΆΠ΅ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ IDL являСтся Π²ΠΏΠΎΠ»Π½Π΅ допустимым ΠΈ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΌ для БОМ:


import Β«unknwn.idlΒ»;

[object, uuid(DF12E151-A29A-11d0-8C2D-0080C73925BA)]

interface IAnimal : IUnknown {

HRESULT Eat(void);

}

[object, uuid(DF12E152-A29A-11d0-8C2D-0080C73925BA)]

interface ICat : IAnimal

{

HRESULT IgnoreMaster(void);

}

[object, uuid(DF12E153-A29A-11d0-8C2D-0080C73925BA)]

interface IDog : IAnimal

{

HRESULT Bark(void);

}

[object, uuid(DF12E154-A29A-11d0-8C2D-0080C73925BA)]

interface IPug : IDog

{

HRESULT Snore(void);

}

[object, uuid(DF12E155-A29A-11d0-8C2D-0080C73925BA)]

interface IOldPug : IPug

{

HRESULT SnoreLoudly(void);

}


БОМ Π½Π°ΠΊΠ»Π°Π΄Ρ‹Π²Π°Π΅Ρ‚ ΠΎΠ΄Π½ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ Π½Π° наслСдованиС интСрфСйсов: интСрфСйсы БОМ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ прямыми ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ°ΠΌΠΈ Π±ΠΎΠ»Π΅Π΅ Ρ‡Π΅ΠΌ ΠΎΠ΄Π½ΠΎΠ³ΠΎ интСрфСйса. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ Π² БОМ нСдопустим:


[object, uuid(DF12E156-A29A-11d0-8C2D-0080C73925BA)]

interface ICatDog : ICat, IDog

{

// illegal, multiple bases

// Π½Π΅Π²Π΅Ρ€Π½ΠΎ, нСсколько Π±Π°Π·ΠΎΠ²Ρ‹Ρ… интСрфСйсов

HRESULT Meowbark(void);

}


БОМ Π·Π°ΠΏΡ€Π΅Ρ‰Π°Π΅Ρ‚ наслСдованиС ΠΎΡ‚ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… интСрфСйсов ΠΏΠΎ Ρ†Π΅Π»ΠΎΠΌΡƒ ряду ΠΏΡ€ΠΈΡ‡ΠΈΠ½. Одна ΠΈΠ· Π½ΠΈΡ… состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π΄Π²ΠΎΠΈΡ‡Π½ΠΎΠ΅ прСдставлСниС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ абстрактного Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса C++ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ нСзависимым ΠΎΡ‚ компилятора. Π’ этом случаС БОМ ΡƒΠΆΠ΅ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠ²Π»ΡΡ‚ΡŒΡΡ Π΄Π²ΠΎΠΈΡ‡Π½Ρ‹ΠΌ стандартом, нСзависимым ΠΎΡ‚ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°. Другая ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π° кроСтся Π² тСсной связи ΠΌΠ΅ΠΆΠ΄Ρƒ БОМ ΠΈ DCE RPC. ΠŸΡ€ΠΈ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΈ наслСдования интСрфСйсов ΠΎΠ΄Π½ΠΈΠΌ Π±Π°Π·ΠΎΠ²Ρ‹ΠΌ интСрфСйсом ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρƒ интСрфСйсами БОМ ΠΈ интСрфСйсными Π²Π΅ΠΊΡ‚ΠΎΡ€Π°ΠΌΠΈ DCE RPC Π²ΠΏΠΎΠ»Π½Π΅ ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎ. Π’ ΠΊΠΎΠ½Ρ†Π΅ ΠΊΠΎΠ½Ρ†ΠΎΠ², отсутствиС ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Π±Π°Π·ΠΎΠ²Ρ‹Ρ… интСрфСйсов Π½Π΅ являСтся ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ΠΌ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ каТдая рСализация ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ для открытия ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ интСрфСйсов, сколько ΠΏΠΎΠΆΠ΅Π»Π°Π΅Ρ‚. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ основанный Π½Π° БОМ Cat/Dog ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ допустим Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ:


class CatDog : public ICat, public IDog

{

//

...

};

ΠšΠ»ΠΈΠ΅Π½Ρ‚, ΠΆΠ΅Π»Π°ΡŽΡ‰ΠΈΠΉ Ρ‚Ρ€Π°ΠΊΡ‚ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΊΠ°ΠΊ Cat/Dog, просто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ QueryInterface для привязки ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ ΠΎΠ±ΠΎΠΈΡ… Ρ‚ΠΈΠΏΠΎΠ² ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ. Если ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² QueryInterface Π½Π΅ достигаСт успСха, Ρ‚ΠΎ Π΄Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π½Π΅ являСтся Cat/Dog ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒΡΡ с этим, ΠΊΠ°ΠΊ сумССт. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Ρ‚ΡŒ нСсколько интСрфСйсов, Ρ‚ΠΎ Π·Π°ΠΏΡ€Π΅Ρ‚ для интСрфСйсов Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ Ρ‡Π΅ΠΌ ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠ³ΠΎ интСрфСйса являСтся лишь нСбольшой ΠΏΠΎΡ‚Π΅Ρ€Π΅ΠΉ Π² смыслС сСмантичСской ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ Ρ‚ΠΈΠΏΠ΅.

БОМ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ стандарт ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊΠΈΠ΅ интСрфСйсы доступны ΠΈΠ· ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Π­Ρ‚ΠΎΡ‚ способ придСрТиваСтся философии БОМ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ отдСлСния интСрфСйса ΠΎΡ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈ Π½Π΅ раскрываСт Π½ΠΈΠΊΠ°ΠΊΠΈΡ… Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈΠ½Π°Ρ‡Π΅, Ρ‡Π΅ΠΌ Ρ‡Π΅Ρ€Π΅Π· список выставляСмых ΠΈΠΌ интСрфСйсов.



Рисунок 2.4 ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ стандартноС ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ класса CatDog. Π—Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΈΠ· этой схСмы ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ СдинствСнный Π²Ρ‹Π²ΠΎΠ΄: Ссли Π½Π΅ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚ катастрофичСских сбоСв, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ CatDog выставят Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ интСрфСйса: ICat, IDog, IAnimal ΠΈ IUnknown.


Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ рСсурсами ΠΈ IUnknown

Как Π±Ρ‹Π»ΠΎ Π² случаС с DuplicatePointer ΠΈ DestroyPointer ΠΈΠ· ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ Π³Π»Π°Π²Ρ‹, ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ AddRef ΠΈ Release ΠΈΠ· IUnknown ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΡ‡Π΅Π½ΡŒ простой ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ», ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€ΠΈΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒΡΡ всС, ΠΊΡ‚ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ указатСлями этих интСрфСйсов. Π­Ρ‚ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°ΡŽΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΎΡ‚ нСобходимости ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΊΠΎΠ³Π΄Π° нСсколько интСрфСйсных ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΌΠΎΠ³ΡƒΡ‚ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ Π½Π΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. ΠšΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ простым ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ AddRef/Release Π΅Π΄ΠΈΠ½ΠΎΠΎΠ±Ρ€Π°Π·Π½ΠΎ для всСх интСрфСйсных ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ ΠΈΠΌ приходится ΡΡ‚Π°Π»ΠΊΠΈΠ²Π°Ρ‚ΡŒΡΡ, Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π±ΡƒΠ΄Π΅Ρ‚ сам ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ своим Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ.

БпСцификация ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π½Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² (Component Object Model Specification) содСрТит Ρ‡Π΅Ρ‚ΠΊΠΈΠ΅ опрСдСлСния ΠΏΡ€Π°Π²ΠΈΠ» подсчСта ссылок БОМ. ПониманиС ΠΌΠΎΡ‚ΠΈΠ²ΠΈΡ€ΠΎΠ²ΠΊΠΈ этих ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ€Π΅ΡˆΠ°ΡŽΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈ БОМ-ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ Π½Π° C++. Π­Ρ‚ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Π° БОМ ΠΎ подсчСтС ссылок ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ свСдСны ΠΊ Ρ‚Ρ€Π΅ΠΌ простым аксиомам:

Когда Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ интСрфСйса копируСтся ΠΈΠ· ΠΎΠ΄Π½ΠΎΠΉ ячСйки памяти Π² Π΄Ρ€ΡƒΠ³ΡƒΡŽ, Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒΡΡ AddRef для извСщСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ссылкС.