标题: VB6拾遗:IUnknown接口与COM对象
作者: Demon
链接: https://demon.tw/programming/vb6-repick-iunknown-com.html
版权: 本博客的所有文章,都遵守“署名-非商业性使用-相同方式共享 2.5 中国大陆”协议条款。
VB6是建立在COM之上的,所有的COM对象都必须实现IUnknown接口。
IUnknown接口的IDL定义如下:
interface IUnknown { HRESULT QueryInterface( [in] REFIID riid, [out, iid_is(riid)] void **ppvObject); ULONG AddRef(); ULONG Release(); }
QueryInterface用于接口查询,AddRef和Release用于引用计数。
COM是很复杂的东西,不是一两句话能够说得清楚的,感兴趣的话可以看看《COM原理与应用》、《COM技术内幕》、《COM本质论》等书籍。
VB6将复杂的COM都隐藏起来了,使得COM对象使用起来非常的简单:
Sub Main() Dim o1 As Collection Dim o2 As Object Dim o3 As Control Set o1 = New Collection Set o2 = o1 Set o3 = o1 End Sub
生成的汇编代码如下:
00401891 push ___vba@095E3C24 ; /Arg1 = Project1.___vba@095E3C24 00401896 call ___vbaNew ; \MSVBVM60.__vbaNew 0040189B push eax ; /Arg2 0040189C lea eax, [ebp-14] ; | 0040189F push eax ; |Arg1 => offset LOCAL.5 004018A0 call ___vbaObjSet ; \MSVBVM60.__vbaObjSet 004018A5 push dword ptr [ebp-14] ; /Arg2 => [LOCAL.5] 004018A8 lea eax, [ebp-18] ; | 004018AB push eax ; |Arg1 => offset LOCAL.6 004018AC call ___vbaObjSetAddref ; \MSVBVM60.__vbaObjSetAddref 004018B1 push ___vba@095E3C38 ; /Arg2 = Project1.___vba@095E3C38 004018B6 push dword ptr [ebp-14] ; |Arg1 => [LOCAL.5] 004018B9 call ___vbaCastObj ; \MSVBVM60.__vbaCastObj 004018BE push eax ; /Arg2 004018BF lea eax, [ebp-1C] ; | 004018C2 push eax ; |Arg1 => offset LOCAL.7 004018C3 call ___vbaObjSet ; \MSVBVM60.__vbaObjSet 004018C8 push 004018E6 004018CD lea ecx, [ebp-14] 004018D0 call @__vbaFreeObj ; [MSVBVM60.__vbaFreeObj 004018D5 lea ecx, [ebp-18] 004018D8 call @__vbaFreeObj ; [MSVBVM60.__vbaFreeObj 004018DD lea ecx, [ebp-1C] 004018E0 call @__vbaFreeObj ; [MSVBVM60.__vbaFreeObj
__vbaNew函数用于创建对象,__vbaObjSet用于将对象变量指向内存中的对象。
当用一个对象变量给另一个对象变量赋值时,如果两边变量的类型相同,Set赋值时使用__vbaObjSetAddref函数,使其指向同一个对象,并调用该对象的AddRef函数增加引用计数;如果变量的类型不同,Set赋值前调用__vbaCastObj函数,__vbaCastObj内部调用对象的QueryInterface查询对象是否实现了相应的接口,实现了的话则用__vbaObjSet赋值,否则抛出异常“类型不匹配”。
当变量超出作用范围时需要调用__vbaFreeObj函数,与函数的名称不符,该函数并不一定会释放对象所占用的内存,而只是调用对象的Release函数减少引用计数,只有当对象的引用计数为0时对象所占的内存才会被释放。
赞赏微信赞赏支付宝赞赏
随机文章:
Hi,Demon,反汇编的注释好详细,可否请教使用的工具信息。万分感谢。