News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

COM definitions

Started by Yuri, February 05, 2010, 08:39:30 AM

Previous topic - Next topic

Yuri

Edgar,

I see that in COM headers you define as an interface what is actually a VTable. What is the reason behind that? Isn't that misleading? When in COM we obtain a pointer to IUnknown, it doesn't mean that we have a pointer to its VTable, we have to dereference it to get the latter. While from your definitions one might think he's already there.

Also, if we get a pointer to the IDispatch VTable, it isn't a pointer to GetTypeInfoCount, but still a pointer to QueryInterface. But you define IDispatch as a separate unit starting with GetTypeInfoCount. In my opinion it can also be confusing.

Of course, correct me if I'm getting something wrong, I am not an expert in this field.  :(

donkey

Hi Yuri,

Well, its a bit of a tradeoff. I have to assume that the person using the COM headers knew a bit about how COM actually works. In order to access the methods you have to use the vTable, everything else outside of its IID and CLSID is pretty much useless from an assembly standpoint and the semantics of C++ though prevalent in the documentation are not applicable to asm. So yes, the vtable is actually defined as an interface however this was intended to make the source more readable, not to explain the inner workings of COM to a newcomer.

CoInvoke(pInterface, IInterface.IUnknown.Release)

When a more semantically correct version would be

CoInvoke(pInterface, vtIInterface.Release)

Readability is the key in the example above, at a glance you can see that I am calling the Release method of the interfaces implementation if IUnknown. The CoInvoke macro is intended to be used with the headers COM interfaces and it takes care of all of the dereferencing for you:

...
push [%pInterface]
mov eax, [%pInterface]
mov eax,[eax]
add eax, %Method
call [eax]


I generally see IUnknown and IDispatch as separate interfaces that must be implemented (well IUnknown anyway) and so I keep them apart from the main vTable and those 2 are explicitly identified in each interface. Again the only reason for this is that it was the way I did it before I started the header project and I decided to keep it for readability rather than clarity since I had not expected many newcomers to use COM anyway.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Yuri

Edgar, two interfaces in unknwn.h remained not changed into the new format — IClassFactory and AsyncIUnknown. Or maybe you are going to abandon this idea due to the initialization issues? I have just started redoing my project that uses COM and am dubious whether to use your headers in it or stay with my old home-made COM defines. Jeremy seems to be very busy offline and who knows when he will be able to fix the problems.

I personally can use the headers even now, because with the help of OllyDbg I have found out what's going wrong inside the curly braces (initialization by member names) and patched the executable (changed JNB to JE). But others may probably have problems with the COM defines in their current state. On the other hand I would certainly like to keep up with the latest version of the headers without the need to overstrain my brains recalling which files should and should not be replaced in the Include folder.

donkey

Hi Yuri,

Well, most interfaces with only a very few exceptions are not meant to be initialized and outside of that one issue there are no problems with the union so I will keep it. I must have missed those 2 interfaces, you can correct them manually if you like and i will include them in the next update. If you are going to be initializing interfaces you might be better off sticking with your home-made COM stuff until the issue is resolved. For myself I rarely build my own COM severs so there is almost never any need to initialize an interface.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Yuri

Since you are keeping the changes, I will transit to your headers. Yes, it's a COM server that can be used in JScript or VBScript, hence my interest in easy IDispatch handling. Anyway this is a hobby project, no time limits or anything, so let it be an experiment.