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

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

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

interface IProgrammer : IUnknown {

HRESULT Advise ([in] ISoftwareConsumer *psc, [out] DWORD *pdwCookie);

: : :

посрСдством ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΠΎΠ΄Π³ΠΎΡ‚Π°Π²Π»ΠΈΠ²Π°Π΅Ρ‚ ΠΏΠ°Ρ€Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚-ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ, Π° программист Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ DWORD для подтвСрТдСния связи. Π—Π°Ρ‚Π΅ΠΌ этот DWORD ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ Unadvise:

interface IProgrammer : IUnknown {

: : :

HRESULT Unadvise([in] DWORD dwCookie);

}

для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ-программисту ΠΎ ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π½ΠΈΠΈ связи. ΠŸΡ€ΠΈ использовании ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… DWORD для прСдставлСния связи программист-ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π΄ΠΈΠ·Π°ΠΉΠ½ интСрфСйса позволяСт ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠΌΡƒ числу ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ нСзависимо Π΄Ρ€ΡƒΠ³ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³Π° ΡΠΎΠ΅Π΄ΠΈΠ½ΡΡ‚ΡŒΡΡ с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ ΠΈ ΠΎΡ‚ΡΠΎΠ΅Π΄ΠΈΠ½ΡΡ‚ΡŒΡΡ ΠΎΡ‚ Π½Π΅Π³ΠΎ.

Если эти Π΄Π²Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΈΠΌΠ΅ΡŽΡ‚ΡΡ Π² интСрфСйсС IProgrammer, Ρ‚ΠΎ рСализация программиста ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ соСдинСна с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ-ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΌ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Advise

STDMETHODIMP Programmer::Advise(ISoftwareConsumer *pcs, DWORD *pdwCookie)

{

assert(pcs);

if (m_pConsumer != 0) // is there already a consumer?

// ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ?

return E_UNEXPECTED;

(m_pConsumer = pcs)->AddRef();

// hold onto new consumer

// соСдиняСмся с Π½ΠΎΠ²Ρ‹ΠΌ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΌ

*pdwCookie = DWORD(pcs);

// make up a reasonable cookie

// Π³ΠΎΡ‚ΠΎΠ²ΠΈΠΌ подходящий ΠΌΠ°Ρ€ΠΊΠ΅Ρ€

return S_OK;

}

Π‘ΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ рСализация ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Unadvise выглядСла Π±Ρ‹ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Ρ‚Π°ΠΊ:

STDMETHODIMP Programmer::Unadvise(DWORD dwCookie)

{

// does the cookie correspond to the current consumer?

// соотвСтствуСт Π»ΠΈ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ Π΄Π°Π½Π½ΠΎΠΌΡƒ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŽ?

if (DWORD(m_pConsumer) != dwCookie)

return E_UNEXPECTED;

(m_pConsumer)->Release();

// release current consumer

// освобоТдаСм Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ потрСбитСля

m_pConsumer = 0;

return S_OK;

}

Π’Π·Π°ΠΈΠΌΠΎΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡ ΠΌΠ΅ΠΆΠ΄Ρƒ программистом ΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΌ ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ‹ Π½Π° рис. 7.7. Π₯отя Π² Π΄Π°Π½Π½ΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π² ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ прСдусмотрСн Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΎΠΏΡ‹Ρ‚Π½Ρ‹ΠΉ программист смог Π±Ρ‹ ΠΎΠΏΠ΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ нСсколькими потрСбитСлями ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ, управляя динамичСским массивом интСрфСйсных ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΈΠ· ISoftwareConsumer.




ИмСя ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΡƒΡŽ Π²Ρ‹ΡˆΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ, ΠΌΠ΅Ρ‚ΠΎΠ΄ программиста StartHacking ΠΌΠΎΠΆΠ΅Ρ‚ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ потрСбитСля для ΠΈΠ½Π΄ΠΈΠΊΠ°Ρ†ΠΈΠΈ готовности Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°:

STDMETHODIMP Programmer::StartHacking (void)

{

assert(m_pConsumer);

// preemptively notify of lateness

// ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½ΠΎ сообщаСм ΠΎ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ΅

HRESULT hr = m_Consumer->OnProductWillBeLate(3);

if (FAILED(hr))

return PROGRAMMER_E_UNREALISTICCONSUMER;

// generate some code

// Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΊΠΎΠ΄

extern char *g_rgpszTopFiftyStatements[];

for (int n = 0; n < 100000; n++)

printf(g_rgpszTopFiftyStatements[rand() % 50]);

// inform consumer of done-ness

// ΠΈΠ·Π²Π΅Ρ‰Π°Π΅ΠΌ потрСбитСля ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ

hr = m_pConsumer->OnProductIsDone();

return S_OK;

}

To ΠΎΠ±ΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ, Ρ‡Ρ‚ΠΎ рСализация ISoftwareConsumer ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‚ΡŒ ΠΊ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ Π°ΠΏΠ°Ρ€Ρ‚Π°ΠΌΠ΅Π½Ρ‚Ρƒ, Ρ‡Π΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚-программист, Π½Π΅ являСтся сущСствСнным. На самом Π΄Π΅Π»Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ StartHacking ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹Π·Π²Π°Π½ ΠΈΠ· Ρ‚ΠΎΠ³ΠΎ Π°ΠΏΠ°Ρ€Ρ‚Π°ΠΌΠ΅Π½Ρ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ содСрТит ΠΎΠ±ΡŠΠ΅ΠΊΡ‚-ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ, ΠΈ Π² этом случаС Π±ΡƒΠ΄Π΅Ρ‚ осущСствлСно ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ΅ Π²Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π² Π°ΠΏΠ°Ρ€Ρ‚Π°ΠΌΠ΅Π½Ρ‚ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Ρ‡Ρ‚ΠΎ, Π² сущности, являСтся синхронным ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹ΠΌ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ. Π’ Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ эта рСализация Π΄Π΅Π»Π°Π΅Ρ‚ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ Π²Ρ‹Π·ΠΎΠ²Ρ‹ Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚-ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚-программист ΠΌΠΎΠΆΠ΅Ρ‚ Ρ‚Π°ΠΊΠΆΠ΅ Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ΡŒ Π²Ρ‹Π·ΠΎΠ²Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°-потрСбитСля Π² любоС врСмя. Π­Ρ‚Π° привилСгия остаСтся Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π½Π΅ послСдуСт Π²Ρ‹Π·ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Unadvise, Ρ€Π°Π·Ρ€Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ соСдинСниС.

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ интСрфСйсы IProgrammer ΠΈ ISoftwareConsumer, вСроятно, Π±Ρ‹Π»ΠΈ созданы Π² Ρ‚Π°Π½Π΄Π΅ΠΌΠ΅ для совмСстной Ρ€Π°Π±ΠΎΡ‚Ρ‹, использованиС явного ΠΌΠ΅Ρ‚ΠΎΠ΄Π° интСрфСйса IProgrammer для установлСния связи становится Ρ‡Π°ΡΡ‚ΡŒΡŽ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ-программистами ΠΈ являСтся Π²ΠΏΠΎΠ»Π½Π΅ цСлСсообразным. Π’ΠΎΡ‚ Ρ„Π°ΠΊΡ‚, Ρ‡Ρ‚ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ программиста способны ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈΠ»ΠΈ нСсколько ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²-ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ ΠΊΠ°ΠΊ Ρ‡Π°ΡΡ‚ΡŒ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° интСрфСйса IProgrammer Π² порядкС уточнСния сСмантичСского ΠΊΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚Π° IProgrammer. Π‘ΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚, ΠΎΠ΄Π½Π°ΠΊΠΎ, сцСнарии, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… интСрфСйсы совмСстной Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½Ρ‹ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ находятся Π²Π½Π΅ области видимости любого Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ интСрфСйса. НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚Π°ΠΊΠΎΠ³ΠΎ интСрфСйса:

[uuid(75DA645D-DD0F-11d0-8C58-0080C73925BA),object ]

interface IShutdownNotify : IUnknown {

HRESULT OnObjectDestroyed([in] IUnknown *pUnk);

}

Π’ этом интСрфСйсС прСдполагаСтся, Ρ‡Ρ‚ΠΎ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ IShutdownNotify заинтСрСсован Π² ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ сообщСний ΠΎ ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‰Π΅Π½ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ². Π’ Π΄Π°Π½Π½ΠΎΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ, ΠΎΠ΄Π½Π°ΠΊΠΎ, Π½Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ, с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ эти заинтСрСсованныС стороны ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ Ρ…ΠΎΡ‚Π΅Π»ΠΈ Π±Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½Ρ‹ ΠΎΠ± ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ΅Π½ΠΈΠΈ этого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Как ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½Π° рис. 7.8, ΠΎΠ΄Π½Π° ΠΈΠ· Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… стратСгий осущСствлСния этого состоит Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ (ΠΏΠ°Ρ€Π½ΠΎΠ³ΠΎ) интСрфСйса, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ:

[uuid(75DA645E-DD0F-11d0-8C58-0080C73925BA), object]

interface IShutdownSource : IUnknown {

HRESULT Advise([in] IShutdownNotify *psn, [out] DWORD *pdwCookie);

HRESULT Unadvise([in] DWORD dwCookie);

}




Π”Π°Π½Π½Ρ‹ΠΉ интСрфСйс сущСствуСт, ΠΎΠ΄Π½Π°ΠΊΠΎ, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄Π°Ρ‚ΡŒ Π½Π°Π±Π»ΡŽΠ΄Π°Ρ‚Π΅Π»ΡΠΌ (observers) Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ свои интСрфСйсы IShutdownNotify с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ. Если имССтся большоС число Ρ‚ΠΈΠΏΠΎΠ² интСрфСйсов ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°, Ρ‚ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΡΡ‚ΠΎΠ»ΡŒ ΠΆΠ΅ большоС число ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… интСрфСйсов Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для управлСния соСдинСниСм. Ясно, Ρ‡Ρ‚ΠΎ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ±Ρ‰ΠΈΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ: Π²Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π² Ρ‚ΠΎΡ‡ΠΊΠ°Ρ… стыковки.

Π’ΠΎΡ‡ΠΊΠΈ стыковки ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΈΠ΄ΠΈΠΎΠΌΠΎΠΉ БОМ, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½ΠΎΠΉ для рСгистрации связи интСрфСйсов ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ ΠΈ Π΅Π΅ ΠΎΡ‚ΠΌΠ΅Π½Ρ‹. Π’ΠΎΡ‡ΠΊΠΈ стыковки Π½Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ΠΌΠΈ для создания сСтСй ΠΈΠ· ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² с большим количСством соСдинСний. К Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ Ρ‚ΠΎΡ‡ΠΊΠΈ стыковки Π½Π΅ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‚ Π΄Π²ΡƒΠ½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹Ρ… соСдинСний. ВмСсто этого ΠΈΠ΄ΠΈΠΎΠΌΠ° Ρ‚ΠΎΡ‡Π΅ΠΊ стыковки Π²Ρ‹Ρ€Π°ΠΆΠ°Π΅Ρ‚ ΠΎΠ±Ρ‰ΡƒΡŽ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΡŽ рСгистрации экспортируСмых интСрфСйсов ΠΊΠ°ΠΊ нСбольшого числа интСрфСйсов стандартной инфраструктуры. НаиболСС Ρ„ΡƒΠ½Π΄Π°ΠΌΠ΅Π½Ρ‚Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΈΠ· этих интСрфСйсов являСтся IConnectionPoint:

[object, uuid(B196B286-BAB4-101A-B69C-00AA00341D07)]

interface IConnectionPoint : IUnknown {

// which type of interface can be connected

// ΠΊΠ°ΠΊΠΎΠΉ Ρ‚ΠΈΠΏ интСрфСйса ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ

HRESULT GetConnectionInterface( [out] IID * pIID);

// get a pointer to identity of Β«realΒ» object

// ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° копию Β«Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎΒ» ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°

HRESULT GetConnectionPointContainer([out] IConnectionPointContainer ** ppCPC);

// hold and use pUnkSink until notified otherwise

// сохраняСм ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ pUnkSink, ΠΏΠΎΠΊΠ° Π½Π΅ объявлСно Π΄Ρ€ΡƒΠ³ΠΎΠ΅

HRESULT Advise([in] IUnknown * pUnkSink, [out] DWORD * pdwCookie);

// stop holding/using the pointer associated with dwCookle

// ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‰Π°Π΅ΠΌ Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅/использованиС указатСля, связанного с dwCookie

HRESULT Unadvise([in] DWORD dwCookie);

// get information about currently held pointers

// ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎΠ± ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ…ΡΡ Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ указатСлях

HRESULT EnumConnections([out] IEnumConnections ** ppEnum);

}

Как ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½Π° рис. 7.9, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ этого интСрфСйса ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ интСрфСйса, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использован ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ Π² качСствС интСрфСйса ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°. Π’Π²ΠΈΠ΄Ρƒ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ IConnectionPoint Π½Π΅ выставлСн ΠΊΠ°ΠΊ Ρ‡Π°ΡΡ‚ΡŒ Π΅Π΄ΠΈΠ½ΠΈΡ†Ρ‹ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΎΠ½ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ посрСдством QueryInterface. ВмСсто этого Π² БОМ прСдусмотрСн Π²Ρ‚ΠΎΡ€ΠΎΠΉ интСрфСйс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ выставлСн ΠΊΠ°ΠΊ Ρ‡Π°ΡΡ‚ΡŒ Π΅Π΄ΠΈΠ½ΠΈΡ†Ρ‹ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, которая позволяСт ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ IConnectionPoint, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ интСрфСйса ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°:

[object,uuid(B196B284-BAB4-101A-B69C-00AA00341D07)]

interface IConnectionPointContainer : IUnknown {

// get all possible IConnectionPoint implementations

// ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ IConnectionPoint

HRESULT EnumConnectionPoints([out] IEnumConnectionPoints ** ppEnum);

// get the IConnectionPoint implementation for riid

// ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ IConnectionPoint для riid

HRESULT FindConnectionPoint([in] REFIID riid, [out] IConnectionPoint ** ppCP);

}




Как ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½Π° рис. 7.9, каТдая рСализация IConnectionPoint выставляСтся ΠΈΠ· ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ БОМ-Π΅Π΄ΠΈΠ½ΠΈΡ†Ρ‹ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ.

Π‘ ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ Π²Ρ‹ΡˆΠ΅ΡƒΠΏΠΎΠΌΡΠ½ΡƒΡ‚Ρ‹Ρ… ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ интСрфСйса ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΌΠΎΠ³ Π±Ρ‹ ΡΠ²ΡΠ·Π°Ρ‚ΡŒ свою Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ IShutdownNotify с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

HRESULT HookupShutdownCallback(IUnknown *pUnkObject,

IShutdownNotify *pShutdownNotify,

DWORD &rdwCookie)

{

IConnectionPointContainer *pcpc = 0;

HRESULT hr = pUnkObject->QueryInterface(IID_IConnectionPointContainer, (void**)&pcpc);

if (SUCCEEDED(hr)) {

IConnectionPoint *pcp = 0;

hr =pcpc->FindConnectionPoint(IID_IShutdownNotify,&pcp);

if (SUCCEEDED(hr)) {

hr = pcp->Advise(pShutdownNotify, &rdwCookie);

pcp->Release();

}

pcpc->Release();

}

}

Π‘ΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ для Ρ€Π°Π·Ρ€Ρ‹Π²Π° связи выглядит Ρ‚Π°ΠΊ:

HRESULT TeardownShutdownCallback(IUnknown *pUnkObject, DWORD dwCookie)

{

IConnectionPointContainer *pcpc = 0;

HRESULT hr = pUnkObject->QueryInterface(IID_IConnectionPointContainer, (void**)&pcpc);

if (SUCCEEDED(hr)) {

IConnectionPoint *pcp = 0;

hr =pcpc->FindConnectionPoint(IID_IShutdownNotify,&pcp);

if (SUCCEEDED(hr)) {

hr = pcp->Unadvise(dwCookie);

pcp->Release();

}

pcpc->Release();

}

}

ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π² ΠΎΠ±ΠΎΠΈΡ… ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ IConnectionPointContainer::FindConnectionPoint для Π²Ρ‹Π·ΠΎΠ²Π° ΠΈΠ· ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π΅Π³ΠΎ IShutdownNotify-Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ IConnectionPoint. Если ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ отклоняСт Π²Ρ‹Π·ΠΎΠ² FindConnectionPoint, это Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π½Π΅ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅Ρ‚ сСмантику интСрфСйса IShutdownNotify. Π­Ρ‚ΠΎ ΠΎΠ±Π΅Ρ€Π΅Π³Π°Π΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΎΡ‚ прикрСплСния ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… интСрфСйсов ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ Π±Π΅Π· ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ согласия Π½Π° это Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.

Как ΠΈ Π² случаС с IUnknown, Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ IConnectionPointContainer ΠΈ IConnectionPoint Π² Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ стСпСни Ρ‚ΠΈΠΏΠΈΡ‡Π½Ρ‹. ΠžΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ C++ трСбуСтся ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Π°Ρ Π΅Π΄ΠΈΠ½ΠΈΡ†Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ БОМ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° экспортируСмого интСрфСйса, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ½ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ. Одна ΠΈΠ· ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ConnectionPoint состоит Π² использовании Ρ‚ΠΎΠ³ΠΎ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΠΈ влоТСния класса/ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ, которая ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅Ρ‚ различия Π² ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡΡ… тоТдСствСнности: