Jump to content

Recommended Posts

Posted
13 hours ago, jugador said:

Another option is to use the Global Interface Table to pass object pointers.

  

On 5/21/2025 at 3:18 PM, jugador said:

the answer to the original post is CoMarshalInterface and CoUnmarshalInterface.

Interesting.  I wouldn't mind having a working example of both your "solutions".  As far I can remember, those cannot be used between processes but only between threads of a single process.

Posted

Yes, the Global Interface Table is used to pass object pointers between threads within a single process.

Using CoMarshalInterface and CoUnmarshalInterface, you can pass pointers between multiple processes (tested with Scripting.Dictionary).

Posted (edited)

Get time to test custom object with CoMarshalInterface and CoUnmarshalInterface function.
worked well between threads within a single process.

But I failed to make it worked between multiple process as the CLSID and IID is not registered.
So to make it work one have to implement IMarshal interface https://learn.microsoft.com/en-us/windows/win32/api/objidl/nn-objidl-imarshal
If the IMarshal interface is not implemented properly then IMarshal::UnmarshalInterface may not be invoked when CoUnmarshalInterface is called.

Global $IID_IMyInterface = "{12345678-9abc-4def-8901-23456789abcd}"
Local $t_TestObj
Local $tagMessage_IUnknown = "GetMessage hresult();"
Local $o_TestObj = _ObjectFromTag("__MyInterface_", $tagMessage_IUnknown, $t_TestObj, Default, $IID_IMyInterface)

 

Code for CoMarshalInterface & CoUnmarshalInterface

; #FUNCTION# =============================================================================
; Name ..........: __CoMarshalInterface
; ========================================================================================
Func __CoMarshalInterface($pStm, $pUnk, $riid = "{00000000-0000-0000-C000-000000000046}", $dwDestContext = 0, $mshlflags = 0)
    Local $triid = __CLSIDFromString($riid)
    Local $aResult = DllCall("ole32.dll", "int", "CoMarshalInterface", "ptr", $pStm, _                      ;~ A pointer to the stream to be used during marshaling.
                                                                       "ptr", DllStructGetPtr($triid), _    ;~ This interface must be derived from the IUnknown interface.
                                                                       "ptr", $pUnk, _                      ;~ This interface must be derived from the IUnknown interface.
                                                                       "dword", $dwDestContext, _           ;~ MSHCTX_LOCAL = 0
                                                                       "ptr", 0, _
                                                                       "dword", $mshlflags)                 ;~ MSHLFLAGS_NORMAL = 0
    If @error Or $aResult[0] <> 0 Then Return SetError(1)
    Return $aResult[0]
EndFunc

; #FUNCTION# =============================================================================
; Name ..........: __CoUnmarshalInterface
; ========================================================================================
Func __CoUnmarshalInterface($pStm, $riid)
    Local $triid = __CLSIDFromString($riid)
    Local $aResult = DllCall("ole32.dll", "int", "CoUnmarshalInterface", "ptr", $pStm, "ptr", DllStructGetPtr($triid), "ptr*", 0)
    If @error Or $aResult[0] <> 0 Then Return SetError(1)
    Return $aResult[3]  ;~ <<==(ppv)Pointer to the unmarshaled interface
EndFunc

I will not try further with a custom object to make it work across multiple processes, as implementing the IMarshal interface is out of my league.

Edit:

I am bad at giving up :D

I managed to implement the IMarshal interface and made a custom object work across multiple processes,
with the help of the IClassFactory interface for temporary registration of the CLSID.
 

Edited by jugador

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...