ObjShare()

Auto Hotkey

ObjShare

Included function to use an object in a multi-threaded environment. This is especially useful to call methods of a class from a different thread. Such objects can be used from multiple threads without causing a crash using COM functions LresultFromObject and ObjectFromLresult.

OutputVar := ObjShare(ObjectOrLresult)
Function Example: Lresult := ObjShare(MyObject)

Parameters

OutputVar

The name of the variable in which to store the Lresult created for object or IDispatch proxy COM object.

ObjectOrLresult

Existing Object or Lresult to use.
When this parameter is an object OutputVar will be Lresult value. Otherwise when Lresult is passed OutputVar will be an IDispatch proxy COM object

General Remarks

AutoHotkey is not thread safe and when you execute code from another thread while main thread is executing code as well it will result in an access violation and your program will crash.

How does ObjShare work:

  • Lresult is created for an object in any exe or dll thread that owns the object.
  • This Lresult is used in a different thread to create an IDispatch proxy COM object that when called will invoke the original object.
  • While IDispatch proxy COM object is processed, the thread where lresult was created will be able to execute any other code before finishing processing.

Note! You cannot access the object in the other thread using ahkExec, ahkFunction or ahkLabel (GoSub mode), this will result in a COM error.

When the thread that created lresult is in critical mode you will not be able to invoke the IDispatch proxy COM object until thread becomes non critical.

To share an object to multiple threads you will need to create a separate lresult for each thread by calling ObjShare multiple times.

Related

Object, CriticalObject

Examples

Gui,Add,Slider,vSlider,50
Gui,Add,CheckBox
Gui,Show,w200 h100
t:=new Test 
lresult := ObjShare(t) ; Create lresult to use in a different thread
AhkThread("
(
    t := ObjShare(%lresult%) ; Create IDispatch proxy COM object
    Loop
        t.CheckBox()
)")
 
Loop
  t.Slider()
return
GuiClose:
ExitApp
Class Test {
  CheckBox(){
    GuiControlGet,value,,Button1
    GuiControl,,Button1,% Value?0:1
  }
  Slider(){
    GuiControlGet,value,,Slider
    if value=100
      value:=0
    GuiControl,,Slider,% Value+1
  }
}