(Sorry my pour English, i can read but i barely write, xD)

What are whe trying to do?

Hello, I?ve been reading your book "Inside ole". I'm barely reading the 2nd chapter and i have questions to make.

BOOL CKoalaA::Init(void)
{
HRESULT hr;

//Create our interface
m_pImpIKoala=new CImpIKoala_A(this);

if (NULL==m_pImpIKoala)
return FALSE;

hr=CreateAnimal(this, IID_IUnknown, (void **)&m_pIUnknown);

if (FAILED(hr))
return FALSE;

hr=m_pIUnknown->QueryInterface(IID_IAnimal, (void **)&m_pIAnimal);
//It will cause increment in the CKoala::m_cRef

if (FAILED(hr))
return FALSE;

m_cRef--;

return TRUE;
}
The code before where extracted from the example of "inside ole" Chapter 2 Objects and Interfaces:Implementing Reusability.
When i first look at this code i didn?t understand what where we trying to do with the m_cRef--.
Then looking up the the CAnimal i understand that it is to decrement the m_cRef that where been incremented in the IUnknown::QueryInterface() non-delegation CAnimal interface, by calling the IUnknown::QueryInterface delegation CAnimal, that its calling our CKoala::QueryInterface.
So that point its cleared.



My second point is about the next pieces of code:

DWORD CKoalaA::Release(void)
{
if (0!=--m_cRef)
return m_cRef;

m_cRef++; //Artificial count preventing reentrancy
delete this;
return 0;
}

CKoalaA::~CKoalaA(void)
{
/*
* Since this KoalaA is not aggregatable, we can use the
* 32-bit rule under Win16 as well.
*/
AddRef();
ReleaseInterface(m_pIAnimal);

ReleaseInterface(m_pIUnknown);
DeleteInterfaceImp(m_pImpIKoala);
return;
}

DWORD CImpIAnimal_A::Release(void)
{
--m_cRef;
return m_pUnkOuter->Release();
//Delegating to the CKoala::Release
}

Well, at firt time i ask my self what its the m_cRef++ in the CKoala::Relase(void), then i realize that the delete this will make execute the CKoala::~CKoala which will try to delete the interface m_pIAnimal, and i see other problem: What its the AddRef(); before delete the interface??
Whell i mentally start emulating the behavior to see what happen, and i found that the key of all where the ReleaseInterface(m_pIAnimal) that will call the m_pIAnimal->Release(), which will delegate to the CKoala::Release.

so i realize that the m_cRef++ folowed by the AddRef(), when the "delete this" call CKoala:~CKoala, will raise the value of m_cRef up to 2 (because at this time m_cRef == 0) and the m_pIAnimal->Release will decrement m_cRef (m_cRef == 1) and this will no cause reentry to the code that call "delete this" in our CKoala::Release().

So i understand that both lines (AddRef() in CKoala::~CKoala, and m_cRef++ in CKoala::Release) are added in consequence to the call m_pIAnimal->Release() in CKoala::~CKoala.

But WHY did we want to call m_pIAnimal->Release() if we know that this will only delegate to CKoala::Release, and how whe know that at this time CKoala::m_cRef it equal to 2, it will only decrement the CKoala::m_cRef, so the only effect of call m_pIAnimal->Release is decrement CKoala::m_cRef

Can we do this instead that?:

DWORD CKoalaA::Release(void)
{
if (0!=--m_cRef)
return m_cRef;

// m_cRef++; //Artificial count preventing reentrancy
delete this;
return 0;
}

CKoalaA::~CKoalaA(void)
{
/*
* Since this KoalaA is not aggregatable, we can use the
* 32-bit rule under Win16 as well.
*/
// AddRef();
// ReleaseInterface(m_pIAnimal);

ReleaseInterface(m_pIUnknown);
DeleteInterfaceImp(m_pImpIKoala);
return;
}

DWORD CImpIAnimal_A::Release(void)
{
--m_cRef;
return m_pUnkOuter->Release();
//Delegating to the CKoala::Release
}
So my question is: "What are we trying to do adding these lines?".

That its my question, and i can not continue reading the book with full trust in my self of what i understand until someone answer me.

__________________Hugo Mauricio Prado Macat

you can contact me at: http://www.asmcommunity.net/board/cryptmail.php?tauntspiders=in.your.face@nomail.for.you&id=140260d4497cdea247f787a656995019,http://www.asmcommunity.net/board/cryptmail.php?tauntspiders=in.your.face@nomail.for.you&id=aca87bf9aed342d0a4d7b11b9e92193e
#ffaabb
Posted on 2004-02-03 16:51:04 by mauricioprado
Have you noticed that this is an ASM forum ?
and COM quizz should be also in ASM :-?
Posted on 2004-02-03 21:21:55 by BogdanOntanu
Afternoon, mauricioprado.

Whose book are you talking about?

Cheers,
Scronty
Posted on 2004-02-04 05:14:39 by Scronty
I know that is in ASM but the code its not complex, i think anyone that know any of COM should understand, much more if you know COM because all the text about that is explained in c/c++.

If you or someone else steel think that i should traduce the code to asm to understand, please ask me to do it.

(sorry my english)

__________________Hugo Mauricio Prado Macat
Posted on 2004-02-04 22:26:36 by mauricioprado
You dont need to traduce the code to asm to understand it, but
the FOCUS of this FORUM is for the ASM PROGRAMMING. Try to find at Google some OLE programming forum in C++ or LEARN Win32ASM, wich are IMO, much better.
Posted on 2004-02-05 07:15:06 by Opcode
I known very much of win32asm, but i wanna to lear COM and i found a book explained in c++, so i'm learning in c fist to can apply in my asm programs

(sorry my english);
Posted on 2004-02-07 21:46:41 by mauricioprado
by the way, did any have a GOOD link to a COM documentation for ASM?
Posted on 2004-02-07 21:48:44 by mauricioprado
Posted on 2004-02-09 07:18:12 by Opcode
I am not a COM expert, but I think all those ++ and -- are just unnecessary tricks, present because the COM object vtable doesn't have the real destructor pointer in it, and "Release" needs to be used, and there might be some people that don't know they actually shouldn't place destruction code in Release, unless they're sure their object won't get inherited by a newer one. In other words:
I think this bunch of C++ code should be cleaned up, and converted like this into asm:



.code

[color=red]include ../CLASS.inc[/color]


[color=blue]class[/color] IUnknown,,COM compatible
virtual QueryInterface:riid,ppvObj
virtual AddRef:
virtual Release:
static RefCount dd 0 [color=seagreen]; this is global[/color]
[color=blue]endclass[/color]

[color=green]IID_IAnimal:[/color]
dd 0BADF00Dh
dw 1111h,2222h
db 1,2,3,4,5,6,7,8 [color=seagreen]; our unique Animal GUID ^_^[/color]

class Animal,IUnknown,COM compatible
virtual Release: [color=seagreen]; override[/color]
virtual Eat:
virtual Sleep:
virtual Miew:
endclass



[color=seagreen];=====[[ IUnknown.funcs >>===\[/color]
IUnknown_IUnknown proc me
inc IUnknown_RefCount
ret
IUnknown_IUnknown endp

IUnknown_$IUnknown proc
dec IUnknown_RefCount
ret
IUnknown_$IUnknown endp

IUnknown_QueryInterface proc me,riid,ppvObj
DoWeSupportGUIDs riid,IID_IAnimal
ret
IUnknown_QueryInterface endp

IUnknown_AddRef proc me
; hell no
ret
IUnknown_AddRef endp

IUnknown_Release proc me
DeleteCOM me,IUnknown
ret
IUnknown_Release endp
[color=seagreen];=======/
;=====[[ IAnimal >>===\[/color]
Animal_Release proc me
DeleteCOM me,Animal
ret
Animal_Release endp

Animal_Animal proc me
ret
Animal_Animal endp

Animal_$Animal proc me
[color=seagreen];--[ here clean up this object's mess ]------\
;....
;--------------------------------------------/[/color]
ret
Animal_$Animal endp

Animal_Eat proc me
ret
Animal_Eat endp


Animal_Sleep proc me
ret
Animal_Sleep endp

Animal_Miew proc me
ret
Animal_Miew endp
[color=seagreen];=======/[/color]


Easy ^_^
Posted on 2004-02-10 09:29:02 by Ultrano
Hi Ultrano.

currently I wouldnt suggest people creating COM objects using your OOP. The simple reason for this is that real life COM objects "inherit" from multiple abstract base classes (= interfaces), or, more technically spoken, they have several vtables, a feature your OOP doesnt support yet if I remember correctly.

Japheth
Posted on 2004-02-16 04:45:14 by japheth
ok :) anyway, I am not thinking of making COM objects any soon - I'm happy my OOP works perfectly with DirectX , which is important to me now :grin:
Posted on 2004-02-16 08:57:19 by Ultrano