本文是MFC与ATL在COM组件开发中的差异和优劣的续篇。
主要是通过C++中的模板和多重继承的语言特性,从ASM汇编层面,来分析MFC与ATL的差异和优劣。
MFC代码部分
MFC中,一个COM类可以包含多个接口,每个接口对象都是一个COM类的成员变量。
例如IWelcome,IMath接口对象就是成员变量m_xWelcome,m_xMath。
var | class | address |
---|---|---|
pThis | CComMFCDemo* | 0x00ff9110 |
pThis->m_xWelcome | CComMFCDemo::XWelcome* | 0x00ff9130 |
pThis->m_xMath | CComMFCDemo::XMath* | 0x00ff9134 |
每当访问接口方法的时候,需要根据当前接口对象指针,计算出COM对象指针,并调用COM对象的功能函数。
计算的方式就是使用METHOD_PROLOGUE()
宏。
#define METHOD_PROLOGUE(theClass, localClass) \
theClass* pThis = \
((theClass*)((BYTE*)this - offsetof(theClass, m_x##localClass))); \
...
#define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
对于接口IWelcome,计算后的COM对象指针为:
METHOD_PROLOGUE(CComMFCDemo, Welcome)
offset = &( ((CComMFCDemo*)0)->m_xWelcome )
pThis = this - offset
对于接口IMath,计算后的COM对象指针为:
METHOD_PROLOGUE(CComMFCDemo, Math)
offset = &( ((CComMFCDemo*)0)->m_xMath )
pThis = this - offset
不同的接口对象,有不同的this地址偏移值。
编译平台(x86)
STDMETHODIMP CComMFCDemo::DUAL_INTERFACE(Welcome)::Greeting(BSTR name, BSTR *message)
{
// this 0x00ff9130 {
...} CComMFCDemo::XWelcome *
METHOD_PROLOGUE(CComMFCDemo, Welcome)