News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Troubles with SafeRelease COM macro

Started by satpro, March 18, 2014, 02:16:42 PM

Previous topic - Next topic

satpro

Hi,

I am having trouble with the following macro while releasing COM interfaces:

SafeRelease(%ppt) MACRO
    mov ecx,[%ppt]
    test ecx, ecx
    jz >

    mov eax,[ecx]
    add eax, 8
    call [eax]
:
endm

Here is the portion of the CoInvoke macro after parameters have been pushed:

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


This is code taken directly from the GoAsm headers (minus the x64 portion).  When I use the SafeRelease macro GoAsm throws this error:

There was a backward short jump to nowhere:-
jz 1


If I use the actual fragment (and not the macro) GoAsm does not throw an error, and the listing itself appears to contain what it should.  I have not yet tested to see if it actually works.

The other question I have is why the contents of the interface ptr are pushed onto the stack in the CoInvoke macro but not in the SafeRelease macro.  Both are calling a COM method, right?  When calling a Release method, should the pointer be cleared afterwards?  It doesn't seem like SafeRelease does that.

Does anybody have any ideas?

Thank you.

Yuri

I found CoInvoke in macros.h but couldn't find SafeRelease anywhere. But you are right, the interface pointer should be passed to the Release method too. Otherwise it will have no access to the object instance that needs to be released, and so what would be the point of calling it at all?

The jz 1 error doesn't show up for me.

satpro

Thanks Yuri.  If I code a proper call to a Release method everything goes okay here, too (no jz 1 error).  I just assumed it was in the header file, but maybe at one time I found it somewhere and put it there?? :dazzled:   Those files do tend to be an accumulation of add-ons and helpers over time, but I know I didn't write that one.  Maybe I should fix that macro.  It's just missing a line or two.

Here is what the whole thing looks like in my headers (right after CoInvoke).  It sure looks official.

// This is equivalent to the SafeRelease macro used in some Microsoft examples
// Syntax requires that no registers are passed and no square brackets are used
// example : SafeRelease(pInterface)
SafeRelease(%ppt) MACRO
    #IF !X64
        mov ecx,[%ppt]
        test ecx,ecx
        jz >
            mov eax,[ecx]
            add eax, 8 // Release
            call [eax]
        :
    #ELSE
        mov rcx,[%ppt]
        test rcx,rcx
        jz >
            sub rsp,32 // Create the shadow space
            mov rax,[rcx]
            add rax, 16 // Release
            call [rax]
            add rsp, 32 // Correct the stack
        :
    #ENDIF
endm // SafeRelease defined


Thanks again.

Yuri

Maybe the author of the macro first wrote its x64 version, where the first parameter is passed in RCX, and then in the x86 version he simply forgot to push it. :icon_rolleyes:

Btw, the x64 version does not align the stack at a 16-bit boundary. Maybe it's better to use Invoke instead of Call because Invoke will take care about the stack before and after the call.

Something like this:


SafeRelease(%ppt) MACRO
    mov rcx,[%ppt]
    jrcxz >
        mov rax,[rcx]
        #if x64
            invoke [rax+16], rcx
        #else
            invoke [eax+8], ecx
        #endif
    :
ENDM