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

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

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

wcscpy(g_wsz, bstr);


Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½ ΠΎΡ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… Π½ΡƒΠ»Π΅Π²Ρ‹Ρ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ:


wcscpy (g_wsz, bstr ? bstr : OLESTR(""));


Для упрощСния использования BSTR Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ ustring.h содСрТится простая встраиваСмая функция:


intline OLECHAR *SAFEBSTR(BSTR b)

{

return b ? b : OLESTR("");

}


Π Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½ΡƒΠ»Π΅Π²Ρ‹Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π² качСствС BSTR Π΄Π΅Π»Π°Π΅Ρ‚ Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ… Π±ΠΎΠ»Π΅Π΅ эффСктивным с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния использования памяти, хотя ΠΈ приходится Π·Π°ΡΠΎΡ€ΡΡ‚ΡŒ ΠΊΠΎΠ΄ этими простыми ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°ΠΌΠΈ.

ΠŸΡ€ΠΎΡΡ‚Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½Ρ‹Π΅ Π½Π° рис. 2.6, ΠΌΠΎΠ³ΡƒΡ‚ ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²Π°Ρ‚ΡŒΡΡ вмСстС с ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ структур языка Π‘. IDL подчиняСтся ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ Π‘ для пространства ΠΈΠΌΠ΅Π½ Ρ‚Π΅Π³ΠΎΠ² (tag namespace). Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ IDL-ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ интСрфСйсов Π»ΠΈΠ±ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ опрСдСлСния Ρ‚ΠΈΠΏΠ° (typedef):


typedef struct tagCOLOR

{

double red;

double green;

double blue;

} COLOR;

HRESULT SetColor([in] const COLOR *pColor);


Π»ΠΈΠ±ΠΎ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово struct для ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΈΠΌΠ΅Π½ΠΈ Ρ‚Π΅Π³Π°:


struct COLOR { double red; double green; double blue; };

HRESULT SetColor([in] const struct COLOR *pColor);


ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½Π΅ΠΉ. ΠŸΡ€ΠΎΡΡ‚Ρ‹Π΅ структуры, ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΉ Π²Ρ‹ΡˆΠ΅, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ ΠΈΠ· Visual Basic, Ρ‚Π°ΠΊ ΠΈ ΠΈΠ· Java. Однако Π² Ρ‚ΠΎ врСмя, ΠΊΠΎΠ³Π΄Π° ΠΏΠΈΡˆΠ΅Ρ‚ΡΡ эта ΠΊΠ½ΠΈΠ³Π°, тСкущая вСрсия Visual Basic ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊ интСрфСйсам, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΌ структуры, Π½ΠΎ ΠΎΠ½Π° Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использована для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ интСрфСйсов, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… структуры ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ².

IDL ΠΈ БОМ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ Ρ‚Π°ΠΊΠΆΠ΅ объСдинСния (unions). Для обСспСчСния ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎΠΉ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ†ΠΈΠΈ объСдинСния IDL Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π² этом объСдинСнии имСлся дискриминатор (discriminator), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π» Π±Ρ‹, ΠΊΠ°ΠΊΠΎΠΉ ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‡Π»Π΅Π½ объСдинСния ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚. Π­Ρ‚ΠΎΡ‚ дискриминатор Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Ρ†Π΅Π»ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° (integral type) ΠΈ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΠΎΡΠ²Π»ΡΡ‚ΡŒΡΡ Π½Π° Ρ‚ΠΎΠΌ ΠΆΠ΅ логичСском ΡƒΡ€ΠΎΠ²Π½Π΅, Ρ‡Ρ‚ΠΎ ΠΈ само объСдинСниС. Если объСдинСниС объявлСно Π²Π½Π΅ области дСйствия структуры, Ρ‚ΠΎ ΠΎΠ½ΠΎ считаСтся нСинкапсулированным (nonencapsulated):


union NUMBER

{

[case(1)] long i;

[case(2)] float f;

};


Атрибут [case] ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ для установлСния соотвСтствия ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Ρ‡Π»Π΅Π½Π° объСдинСния своСму дискриминатору. Для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ²ΡΠ·Π°Ρ‚ΡŒ дискриминатор с нСинкапсулированным объСдинСниСм, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ [switch_is]:


HRESULT Add([in, switch_is(t)] union NUMBER *pn, [in] short t);


Если объСдинСниС Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ вмСстС со своим дискриминатором Π² ΠΎΠΊΡ€ΡƒΠΆΠ°ΡŽΡ‰ΡƒΡŽ структуру, Ρ‚ΠΎ этот составной Ρ‚ΠΈΠΏ (aggregate type) называСтся инкапсулированным, ΠΈΠ»ΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ‡Π΅Π½Π½Ρ‹ΠΌ объСдинСниСм (discriminated union):


struct UNUMBER

{ short t; [switch_is(t)]

union VALUE

{

[case(1)] long i;

[case(2)] float f;

};

};


БОМ прСдписываСт для использования с Visual Basic ΠΎΠ΄Π½ΠΎ ΠΎΠ±Ρ‰Π΅Π΅ Ρ€Π°Π·ΠΌΠ΅Ρ‡Π΅Π½Π½ΠΎΠ΅ объСдинСниС. Π­Ρ‚ΠΎ объСдинСниС называСтся VARIANT[4] ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈΠ»ΠΈ ссылки Π½Π° подмноТСство Π±Π°Π·ΠΎΠ²Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ², ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… IDL. ΠšΠ°ΠΆΠ΄ΠΎΠΌΡƒ ΠΈΠ· ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² присвоСно ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ дискриминатора:


VT_EMPTY nothing

VT_NULL SQL style Null

VT_I2 short

VT_I4 long

VT_R4 float

VT_R8 double

VT_CY CY (64-bit currency)

VT_DATE DATE (double)

VT_BSTR BSTR

VT_DISPATCH IDispatch *

VT_ERROR HRESULT

VT_BOOL VARIANT_BOOL (True=-1, False=0)

VT_VARIANT VARIANT *

VT_UNKNOWN IUnknown *

VT_DECIMAL 16 byte fixed point

VT_UI1 opaque byte


Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Π΄Π²Π° Ρ„Π»Π°Π³Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² сочСтании с Π²Ρ‹ΡˆΠ΅ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΌΠΈ Ρ‚Π΅Π³Π°ΠΌΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π΄Π°Π½Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ (variant) содСрТит ссылку ΠΈΠ»ΠΈ массив Π΄Π°Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°:

VT_ARRAY Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ содСрТит массив SAFEARRAY

VT_BYREF Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ являСтся ссылкой

БОМ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ нСсколько API-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ для управлСния VARIANT:


// initialize a variant to empty

// обнуляСм Π²Π°Ρ€ΠΈΠ°Π½Ρ‚

void VariantInit(VARIANTARG * pvarg);

// release any resources held in a variant

// освобоТдаСм всС рСсурсы, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π² Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π΅

HRESULT VariantClear(VARIANTARG * pvarg);

// deep-copy one variant to another

// ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ ΠΎΠ΄ΠΈΠ½ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π² Π΄Ρ€ΡƒΠ³ΠΎΠΉ

HRESULT VariantCopy(VARIANTARG * plhs, VARIANTARG * prhs);

// dereference and deep-copy one variant into another

// Ρ€Π°Π·Ρ‹ΠΌΠ΅Π½ΠΎΠ²Ρ‹Π²Π°Π΅ΠΌ ΠΈ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ ΠΎΠ΄ΠΈΠ½ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π² Π΄Ρ€ΡƒΠ³ΠΎΠΉ

HRESULT VariantCopyInd(VARIANT * plhs, VARIANTARG * prhs);

// convert a variant to a designated type

// ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅ΠΌ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΊ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ

HRESULT VariantChangeType(VARIANTARG * plhs, VARIANTARG * prhs, USHORT wFlags, VARTYPE vtlhs);

// convert a variant to a designated type

// ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅ΠΌ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΊ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ (с явным ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ ΠΊΠΎΠ΄Π° Π»ΠΎΠΊΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ)

HRESULT VariantChangeTypeEx(VARIANTARG * plhs, VARIANTARG * prhs, LCID lcid, USHORT wFlags, VARTYPE vtlhs);


Π­Ρ‚ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΠΏΡ€ΠΎΡ‰Π°ΡŽΡ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ VARIANT'Π°ΠΌΠΈ. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ эти API-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, рассмотрим ΠΌΠ΅Ρ‚ΠΎΠ΄, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΉ VARIANT Π² качСствС [in]-ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°:


HRESULT UseIt([in] VARIANT var);


Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π° дСмонстрируСт, ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π² этот ΠΌΠ΅Ρ‚ΠΎΠ΄ Ρ†Π΅Π»ΠΎΠ΅ число:


VARIANT var;

VariantInit(&var);

// initialize VARIANT

// ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ VARIANT

V_VT(&var) = VT_I4;

// set discriminator

// устанавливаСм дискриминатор

V_I4(&var) = 100;

// set union

// устанавливаСм объСдинСниС

HRESULT hr = pItf->UseIt(var);

// use VARIANT

// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ VARIANT

VariantClear(&var);

// free any resources in VARIANT

// освобоТдаСм всС рСсурсы VARIANT


ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ этот Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ макросы стандартного аксСссора (accessor) для доступа ΠΊ элСмСнтам Π΄Π°Π½Π½Ρ‹Ρ… VARIANT. Π”Π²Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ строки


V_VT(&var) = VT_I4;

V_I4(&var) = 100;


эквивалСнтны ΠΊΠΎΠ΄Ρƒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ обращаСтся ΠΊ самим элСмСнтам Π΄Π°Π½Π½Ρ‹Ρ…:


var.vt = VT_I4;

var.lVal = 100;


ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½Π΅Π΅, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π½Π° Π‘-трансляторах, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ Π½Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… объСдинСний.

НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΉ Π²Ρ‹ΡˆΠ΅ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ рСализация ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ VARIANT Π² качСствС строки:


STDMETHODIMP MyClass::UseIt( /*[in] */ VARIANT var)

{

// declare and init a second VARIANT

// объявляСм ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π²Ρ‚ΠΎΡ€ΠΎΠΉ VARIANT

VARIANT var2;

VariantInit(&var2);

// convert var to a BSTR and store it in var2

// ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Π² BSTR ΠΈ заносим Π΅Π΅ Π² var2

HRESULT hr = VariantChangeType(&var2, &var, 0, VT_BSTR);

// use the string

// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ строку

if (SUCCEEDED(hr))

{

ustrcpy(m_szSomeDataMember, SAFEBSTR(V_BSTR(&var2)));

// free any resources held by var2

// освобоТдаСм всС рСсурсы, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ var2

VariantClear(&var2);

}

return hr;

}


ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ API-ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° VariantChangeType способна ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒ слоТноС ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ любого ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ Ρ‚ΠΈΠΏΠ° ΠΈΠ· VARIANT Π² Π½ΡƒΠΆΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ (Π² Π΄Π°Π½Π½ΠΎΠΌ случаС BSTR).

Один ΠΈΠ· послСдних Ρ‚ΠΈΠΏΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Π΄ΠΈΡΠΊΡƒΡΡΠΈΡŽ, β€“ это интСрфСйс БОМ. Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡΡ‹ БОМ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Ρ‹ Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· Π΄Π²ΡƒΡ… способов. Если Ρ‚ΠΈΠΏ интСрфСйсного указатСля извСстСн Π½Π° этапС проСктирования, Ρ‚ΠΎ Ρ‚ΠΈΠΏ интСрфСйса ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ объявлСн статичСски:


HRESULT GetObject([out] IDog **ppDog);


Если ΠΆΠ΅ Ρ‚ΠΈΠΏ Π½Π° этапС проСктирования нСизвСстСн, Ρ‚ΠΎ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ интСрфСйса ΠΌΠΎΠΆΠ΅Ρ‚ Π΄Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π·Π°Π΄Π°Ρ‚ΡŒ Ρ‚ΠΈΠΏ Π½Π° этапС выполнСния. Для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ динамичСски Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌΡ‹Ρ… интСрфСйсов Π² IDL имССтся Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ [iid_is]:


HRESULT GetObject([in] REFIID riid, [out, iid_is(riid)] IUnknown **ppUnk);


Π₯отя эта Ρ„ΠΎΡ€ΠΌΠ° Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π²ΠΏΠΎΠ»Π½Π΅ Ρ…ΠΎΡ€ΠΎΡˆΠΎ, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½Π΅Π΅ ΠΈΠ·-Π·Π° Π΅Π³ΠΎ подобия с QueryInterface:


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


Атрибут [iid_is] ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ [in], Ρ‚Π°ΠΊ ΠΈ [out] для Ρ‚ΠΈΠΏΠΎΠ² IUnknown * ΠΈΠ»ΠΈ void *. Для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ интСрфСйса с динамичСски Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ просто ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ IID указатСля Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°:


IDog *pDog = 0; HRESULT hr = pItf->GetObject(IID_IDog, (void**)&pDog);


Π‘ΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ рСализация для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ этого ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° просто использовала Π±Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄ QueryInterface для Π½ΡƒΠΆΠ½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°:


STDMETHODIMP Class::GetObject(REFIID riid, void **ppv)

{

extern IUnknown * g_pUnkTheDog;

return g_pUnkTheDog->QueryInterface(riid, ppv);

}


Для ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡ количСства Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ интСрфСйса с динамичСски Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ всСгда ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ вмСсто ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ интСрфСйса со статичСски Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ IUnknown.


Атрибуты ΠΈ свойства

Иногда Π±Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠΌΠ΅Π΅Ρ‚ Π½Π΅ΠΊΠΈΠ΅ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ свойства, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ доступны ΠΈ/ΠΈΠ»ΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· БОМ-интСрфСйс. БОМ IDL позволяСт Π°Π½Π½ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ интСрфСйса с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π»ΠΈΠ±ΠΎ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π», Π»ΠΈΠ±ΠΎ Ρ‡ΠΈΡ‚Π°Π» ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Рассмотрим Ρ‚Π°ΠΊΠΎΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ интСрфСйса:


[ object, uuid(0BB3DAE1-11F4-11d1-8C84-0080C73925BA) ]

interface ICollie : IDog

{

// Age is a read-only property

// Age (возраст) – это свойство Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния

[propget] HRESULT Age([out, retval] long *pVal);

// HairCount is a read/write property

// HairCount (счСтчик волос) – свойство для чтСния/записи

[propget] HRESULT HairCount([out, retval] long *pVal);

[propput] HRESULT HairCount([in] long val);

// CurrentThought is a write-only property

// CurrentThought (тСкущая ΠΌΡ‹ΡΠ»ΡŒ) – свойство Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для записи

[propput] HRESULT CurrentThought([in] BSTR val);

}


ИспользованиС Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² [propget] ΠΈ [propput] ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ компилятор IDL, Ρ‡Ρ‚ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΅ΠΌΡƒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚, Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Ρ‹ Π² ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ свойств (property mutators) ΠΈΠ»ΠΈ Π² аксСссоры Π½Π° языках, явно ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΡ… свойства. ΠŸΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊ Visual Basic это ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ элСмСнтами Age, HairCount ΠΈ CurrentThought ΠΌΠΎΠΆΠ½ΠΎ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ‚ΠΎΡ‚ ΠΆΠ΅ синтаксис, ΠΊΠ°ΠΊ ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΊ элСмСнтам структуры: