jugador Posted May 23 Author Posted May 23 Another option is to use the Global Interface Table to pass object pointers.
Nine Posted May 23 Posted May 23 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. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
jugador Posted May 24 Author Posted May 24 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).
argumentum Posted May 24 Posted May 24 16 hours ago, Nine said: I wouldn't mind having a working example 6 hours ago, jugador said: Using CoMarshalInterface and CoUnmarshalInterface, you can pass pointers between multiple processes (tested with Scripting.Dictionary). @jugador, would you post an example script to show it working ? Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
jugador Posted May 27 Author Posted May 27 (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 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 May 29 by jugador argumentum 1
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now