VS2015 C++ / Windows7 SP1
考虑以下代码:
CComPtr<IFontDisp> m_pFont;
::OleCreateFontIndirect(&fdesc,IID_IFontDisp,(void**)&m_pFont);
VARIANT var = m_pFont; // PSEUDO CODE
在这之后,
var.vt = 9; //VT_DISPATCH
var.DISPATCH = "oleaut32.dll/IFontDisp"
所以一切看起来都很好。现在我打电话
::VariantClear(var);
我调试到(ASM),我发现了这个:
74CB2EA6 nop
CFont::Release:
--> 74CB2EA7 sub dword ptr [esp+4],4
74CB2EAC jmp CFont::Release (74CB2E79h)
74CB2EAE nop
74CB2EAF nop
74CB2EB0 nop
按照代码:
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
如我所见,它释放了 COM 接口。但是,如果我看到有关 VariantClear 的MSDN 文档:
如果要清除的变量是通过引用传递的 COM 对象,则 pvarg 参数的 vtfield 为 VT_DISPATCH | VT_BYREF 或 VT_UNKNOWN | VT_BYREF。在这种情况下,VariantClear 不会释放对象。因为被清除的变体是一个指向对象引用的指针,所以 VariantClear 无法确定是否需要释放该对象。因此,调用者有责任酌情释放或不释放对象。
据此,它不应该在 IFontDisp 上调用 release。
谁能解释这里发生了什么?
谢谢。