But this should be OK

.if eax == S_OK
mov edx, pishl
mov edx,
push edx ; <=== place a "push" here
call .d ; .Release
.endif


I'm not sure... there's my *working* masm's listing



mDirect MusicSegment, Release
2C if ErrorTest
68 00000A06 R 2C push ??08EC
8B 85 0000014C 2C mov eax , def_int
50 2C push eax
8B 00 2C mov eax , [eax]
2C if ErrorTest
68 00001DD2 R 2C push Error_Test
FF 60 08 2C jmp [??08E7.Release+eax]
2C else
2C call [??08E7.Release+eax]
2C endif
2C ??08EC equ $


I think this should work, too
        mov edx, pishl

push edx
mov edx, [edx]
call .d[edx+8] ; .Release
Posted on 2003-09-04 03:58:13 by S.T.A.S.
Originally posted by S.T.A.S.
I think this should work, too
        mov edx, pishl

push edx
mov edx, [edx]
call .d[edx+8] ; .Release



Yeah, my mistake :) Of course it should be this way.
Posted on 2003-09-04 04:05:48 by Morris
Look at the comtest.asm file. You'll see that it's very much like C++ and much simpler than any other implementation I've seen for masm.

It uses the '@' operator instead of C++'s '.' operator as a 'function member' delimiter.



main proc
local sr:WIN32_FIND_DATA, des[260]:byte

IShellLink ishl ; instance

ishl@getinst @ CLSID_ShellLink, @ IID_IShellLink
.if eax == S_OK
ishl@SetPath "%windir%\explorer.exe" ; 'SetPath' method
ishl@SetDescription "my description" ; 'SetDescription' method
ishl@GetPath dll$, 260, @ sr, 0 ; 'GetPath' method
ishl@GetDescription @ des, 260 ; 'GetDescription' method
ishl@Release
msgbox @ des, dll$
.endif
ret
Posted on 2003-09-04 04:09:12 by gfalen
It will take me some time to come up with a self contained com.inc file that has no dependencies on my other macro files. Later today I should have an upload ready. Til then if you can get the current file(s) to work fine.

This is all free s/w with no copyright(s).
Posted on 2003-09-04 04:22:57 by gfalen
Looks very nice...
I'm using some ugly macros I've writen when some time ago...
That's why I sometimes look at the listing...

...but, does
mov edx, pishl
push edx
mov edx,
call .d ; .Release
work or not?
Posted on 2003-09-04 04:30:50 by S.T.A.S.
...but, does
mov edx, pishl
push edx
mov edx,
call .d ; .Release
work or not?

Yes - for the 'Relase' method (or any method that has no parameters) it will work. But if you try to call a method with args, pishl which is the THIS_ ptr, must be pushed last.

STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv) PURE;

That's why i use this:

mov edx, pishl
mov edx,
invoke (ISomeInterface ptr ).method, pishl, arg1, arg2...
-or-
invoke (ISomeInterface ptr , pishl, arg1, arg2...


The Com.inc file makes this all automatic. You just say:

pishl@QuerryInterface ...
-or-
pishl@Getpath ...

or whatever and the macros do it all for you. Just like C++.
Posted on 2003-09-04 04:51:24 by gfalen

Yes - for the 'Relase' method (or any method that has no parameters) it will work. But if you try to call a method with args, pishl which is the THIS_ ptr, must be pushed last.


My macro works in both cases (my COM experience is just DX)
It's probably one of the first macros I've writen, so might be optimized I think...
This don't cares about number of arguments, but Error_Test proc will check returned code and show the truth...


; remember not to use EAX in arglist before any ADDR (if present) derective !
ErrorTest = TRUE
COMInvoke MACRO InterfaceVtbl_, method_, lpvtbl_, arglist :VARARG
LOCAL arglinv, arg, arg1, exit
if ErrorTest
push exit
endif
IFNB <arglist>
arglinv TEXTEQU <>
% for arg, <arglist>
arglinv CATSTR <arg>, <!,>, arglinv
endm
arglinv SUBSTR arglinv, 1, @SizeStr( %arglinv ) - 1
% for arg, <arglinv>;:VARARG
IF @InStr (1, arg, <ADDR>)
arg1 SUBSTR <arg>, 5
lea eax,[arg1]
push eax
ELSE
push arg
ENDIF
endm
ENDIF
mov eax , lpvtbl_
push eax
mov eax , [eax]
method_ CATSTR <StM_>,<&method_>
if ErrorTest
push Error_Test
jmp [InterfaceVtbl_.method_+eax]
else
call [InterfaceVtbl_.method_+eax]
endif
exit equ $
ENDM

mDirect MACRO mname:REQ, method :REQ, interface:=<>, arglist :VARARG
LOCAL vtbl_name, def_unt
if @SizeStr(interface)
def_int equ interface
else
def_int CATSTR <p_Direct>,<&mname>
endif
vtbl_name CATSTR <IDirect>,<&mname>,<Vtbl>
COMInvoke vtbl_name, method, def_int, arglist
ENDM


I use "mDirect MusicSegment, Release"
or
mDirect MusicPerformance, Init, , ADDR MAIN.Music.pDirectMusic, 0,0

I don't like C because I need *often* use shift key ;)
Posted on 2003-09-04 05:22:54 by S.T.A.S.