0

VS2015 C++ / Windows7 SP1

Considering the following code:

CComPtr<IFontDisp> m_pFont;
::OleCreateFontIndirect(&fdesc,IID_IFontDisp,(void**)&m_pFont);
VARIANT var = m_pFont; // PSEUDO CODE

after this,

var.vt = 9; //VT_DISPATCH
var.DISPATCH = "oleaut32.dll/IFontDisp"

So all looks fine. Now I call

::VariantClear(var);

And I debug into (ASM), I found this:

    74CB2EA6  nop  
    CFont::Release:
--> 74CB2EA7  sub         dword ptr [esp+4],4  
    74CB2EAC  jmp         CFont::Release (74CB2E79h)  
    74CB2EAE  nop  
    74CB2EAF  nop  
    74CB2EB0  nop  

Following the code:

CFont::Release:
--> 74CB2E79  mov         edi,edi  
74CB2E7B  push        ebp  
74CB2E7C  mov         ebp,esp  
74CB2E7E  push        esi  
74CB2E7F  mov         esi,dword ptr [ebp+8]  
74CB2E82  push        edi  
74CB2E83  lea         eax,[esi+0A8h]  
74CB2E89  push        eax  
74CB2E8A  call        dword ptr [__imp__InterlockedDecrement@4 (74C91298h)]  
74CB2E90  mov         edi,eax  
74CB2E92  test        edi,edi  
74CB2E94  je          CFont::Release+261h (74CB30DAh)  
74CB2E9A  mov         eax,edi  
74CB2E9C  pop         edi  
74CB2E9D  pop         esi  
74CB2E9E  pop         ebp  
74CB2E9F  ret         4  

So as I see, it releases the COM interface. But if I see MSDN doc about VariantClear:

if the variant to be cleared is a COM object that is passed by reference, the vtfield of the pvargparameter is VT_DISPATCH | VT_BYREF or VT_UNKNOWN | VT_BYREF. In this case, VariantClear does not release the object. Because the variant being cleared is a pointer to a reference to an object, VariantClear has no way to determine if it is necessary to release the object. It is therefore the responsibility of the caller to release the object or not, as appropriate.

According to this, it should not call release on the IFontDisp.

Can anybody explain what is going on here?

Thanks.

Zoli
  • 841
  • 8
  • 31
  • 4
    but you have no `VT_BYREF` here. so all is correct - `VariantClear` and must release interface (`pdispVal`) – RbMm Oct 29 '18 at 09:44
  • Oh man, I read that quickly with C++ eyes, so thought "is VT_DISPATCH | VT_BYREF" = "is VT_DISPATCH **or** VT_BYREF". My bad, **thank you**. If you write this as answer I can accept it. – Zoli Oct 29 '18 at 10:01
  • `VT_DISPATCH | VT_BYREF` mean that `ppdispVal` used - *A pointer to a pointer to an object was specified*. but you have `VT_DISPATCH` - *A pointer to an object was specified. The pointer is in `pdispVal`* – RbMm Oct 29 '18 at 10:06
  • Yes, thanks, it's clear now – Zoli Oct 29 '18 at 10:08

0 Answers0