Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

AutoHotkey.dll


  • Please log in to reply
1328 replies to this topic
majkinetor
  • Moderators
  • 4512 posts
  • Last active: Jul 29 2016 12:40 AM
  • Joined: 24 May 2006

Updated test version (including exe, dlls and bin)

Looks great. Thanks.
Posted Image

Learning one
  • Members
  • 1483 posts
  • Last active: Jan 02 2016 02:30 PM
  • Joined: 04 Apr 2009
@HotKeyIt: Thanks! I understand it now.

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
For the test version I have changed DynaCall to support only one parameter definition since it reduces code a lot and should be the only way to go.
Small fix for pointer definition pP*, so now UIP, uip and ui* can be specified in parameter definition.
So now maximally 2 parameters can be passed: DynaCall("path and function of dll or function pointer", "parameter definition")
See this post for more information.
Also DynaCall uses only objects now instead #include <map> to save DYNATOKEN (reduces size of exe, dll, bin).

EDIT:
Updated AhkDllThread() function to use with compiled and not compiled scripts.
When using in compiled script, do not forget to Fileinstall,...dll,...dll.
For example:
If 0
	FileInstall,AutoHotkeyMini.dll,AutoHotkeyMini.dll
ahk:=AhkDllThread("AutoHotkeyMini.dll")
ahk.ahktextdll("MsgBox Thread")
MsgBox % ahk.ahkgetvar.A_Now
AhkDllThread(dll=""){
   static
   local v,v1,v2
   static ResourceLoadLibrary:="ResourceLoadLibrary"
   static functions="
	(LTrim Join `n
	ahkdll:ui=sss|ahktextdll:ui=sss|ahkReady:ui=|ahkReload:ui=|ahkTerminate:i=i|
	addScript:ui=sucuc|ahkassign:i=ss|ahkExecuteLine:ui=uiuiui|addFile:ui=sucuc|
	ahkFindFunc:ui=s|ahkFindLabel:ui=s|ahkgetvar:s=sui|ahkLabel:ui=s|ahkPause:i=s"
	)
	If !(dll){
      Loop % i
      {
         idx:=A_Index
         Loop,Parse,functions,|
            DynaCall(dll%idx% . "\" . A_LoopField)
         MemoryFreeLibrary(dllmodule%A_Index%)
         obj%A_Index%:="",dll%A_Index%:="",dllmodule%A_Index%:=""
      }
      i=0
      return
   } else if (!FileExist(dll) && !A_IsCompiled){
      MsgBox File: %dll%`ndoes not exist`, provide correct path for AutoHotkey.dll
      ExitApp
   }
   i++
   dllmodule%i%:=A_IsCompiled ? %ResourceLoadLibrary%(dll) : MemoryLoadLibrary(dll)
   object := Object()
   Loop,Parse,functions,|
   {
      StringSplit,v,A_LoopField,:
      object[v1]:=DynaCall(MemoryGetProcAddress(dllmodule%i%,v1),v2)
   }
   obj%i%:=object
   dll%i%:=dll
   return obj%i%
}


HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
I have wrapped exported functions of AutoHotkey_H.exe.
AhkExported(){
	static init
	static functions:="ahkassign:i=ss|ahkExecuteLine:ui=uiuiui|ahkFindFunc:ui=s|ahkFindLabel:ui=s|ahkgetvar:s=sui|ahkLabel:ui=s|ahkPause:i=s"
	If (!init && init := Object())
   {
		If !A_IsCompiled	
			functions .= "|addFile:ui=sucuc|addScript:ui=sucuc"
      VarSetCapacity(file,512)
      DllCall("GetModuleFileName","UInt",DllCall("GetModuleHandle","UInt",0),"Uint",&file,"UInt",512)
      DllCall("LoadLibrary","Str",(A_IsCompiled ? A_ScriptFullPath : A_AhkPath))
      Loop,Parse,functions,|
      {
         StringSplit,v,A_LoopField,:
         init[v1]:=DynaCall((A_IsCompiled ? A_ScriptFullPath : A_AhkPath) . "\" . v1,v2)
      }
   }
	return init
}
So a dll can now access main script as easy as main script the dll :D
This script will work for compiled and not compiled scripts.
If 0
   FileInstall,AutoHotkey.dll,AutoHotkey.dll
SetWorkingDir % A_ScriptDir
exe:=AhkExported()
dll:=AhkDllThread("AutoHotkey.dll")
dll.ahktextdll[  "exe:=Object(" . &exe . ")`n"
               . "MsgBox AutoHotkey.dll jump to label in AutoHotkey.exe`n"
               . "exe.ahkLabel[""label""]" ]

MsgBox GoSub
Gosub, label
ExitApp
label:
MsgBox Hello World!
Return


HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
AutoHotkey_H Documentation

DynaCall Objects

Following calls will all do the same, just use the one which is appropriate:
dll.ahkassign.var := value
dll.ahkassign[color=red].[/color]("var",value)
dll.ahkassign("var",value)
dll.ahkassign[color=red].var[/color](value)
dll.ahkassign[color=red][[/color]"var",value[color=red]][/color]
;this will work as well
MsgBox % ahk.ahkgetvar.var ;it is the same as
MsgBox % ahk.ahkgetvar["var"] ;...

AutoHotkey Download ( incl. AhkDll.chm + AhkExported() + AhkDll(Object/Thread) )

I have also build in functions Lock() and Unlock() to work with critical section because they are faster than user defined functions.
If 0 ;AutoHotkeyMini.dll will be included in Compiled exe but never extracted, istead it is loaded via AhkDllThread()
   FileInstall,AutoHotkeyMini.dll,AutoHotkeyMini.dll 
SetWorkingDir % A_ScriptDir               ;not required for compiled script
#:=CriticalSection()                      ;see http://www.autohotkey.com/forum/viewtopic.php?t=51335
exe:=AhkExported()                        ;exported AutoHotkey.exe functions to DynaCall objects
SplashTextOn,200,0,Loading Threads... Please wait...
Loop 10
{
   dll:=AhkDllThread("AutoHotkeyMini.dll") ;exported AutoHotkeyMini.dll functions to DynaCall objects
   dll.ahktextdll[  "exe:=Object(" . &exe . ")`nCoordMode,ToolTip,Screen`nSleep,100`nSetBatchLines,-1`n"
               . "Loop`n"                 ;dynamic script
               . "ToolTip % Lock(" . # . ") . exe.ahkFunction[""func"",A_Index . """"] . UnLock(" . # . "),0," ((A_Index-1) * 20) ]
   dll.ahkPause(1),dll%A_Index%:=dll      ;pause thread
}
Loop 10                                   ;unpause threads
   dll:=dll%A_Index%,dll.ahkPause(0)       ;that way all threads will start at once
SplashTextOff
MsgBox Press OK to exit
ExitApp
func(p1){ ;this function is launched by each thread separately
   Return p1
}


basi
  • Members
  • 8 posts
  • Last active: Jan 11 2011 07:49 PM
  • Joined: 28 May 2007
Hi Hotkeyit,

I am having trouble using the \ahkdll function from the latest build (HotKeyIt's version) referenced here : http://www.autohotke...yIt/AutoHotkey/


I am trying to run the example script from the documentaion here: <!-- m -->http://www.autohotke... ... ahkdll.htm<!-- m -->

Host Script
ahkdll := DllCall("LoadLibrary", "str", A_ScriptDir . "\AutoHotkey.dll")
sleep, 500
threadH := DllCall(A_ScriptDir . "\AutoHotkey.dll\ahkdll", "str", "dllclient.ahk", "str"
, "", "str", "parameter1 parameter2", "Cdecl Int") 

Client Script
; dllclient.ahk
#Persistent
msgbox % "script parameters =" . A_ScriptParams . "script options = "
. A_ScriptOptions 
return


If I use tinku99 version of autohotkey.dll the test script runs fine. But when I use the L48H6 build, the script running from the DLL errors out. The error box says something to the effect of:

Error at line 1.
Line Text:  MZ%$^#&           <--  random text/characters here
Error: This line does not contain a recognized action.
The program will exit.

A am also runing the script withe the version of autohotkey.exe that you provide with the downloand (Not Chris's version).
I can get the script to run if I use the \ahktextdll function (and insert the script inline, so to speak).
Any help would be appreciated.

Thanks, -Basi

BTW: Thank you and tinku99 for making this great DLL.[/url]

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Merged with AHK_L latest build
AutoHotkey_L49H8

wiseley
  • Members
  • 29 posts
  • Last active: Sep 30 2011 11:12 PM
  • Joined: 22 Apr 2009
HotKeyIt, can you please give me a little example of how to call AutoHotkey.dll from C. :(

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
See example from tinku99

wiseley
  • Members
  • 29 posts
  • Last active: Sep 30 2011 11:12 PM
  • Joined: 22 Apr 2009
Hotkey, I tried this
#include <windows.h>
#include <stdio.h>
 

typedef int (*ahkdll)(char *, char *, char *) ;
 
int main()
{
	
	ahkdll ahkdll_;
 
	// Load DLL file
	HINSTANCE hinstLib = LoadLibrary("AutoHotkey.dll");
	if (hinstLib == NULL) 
	{
		printf("ERROR: unable to load DLL\n");
		return 1;
	}
	
	
	// Get function pointer
	ahkdll_ = (ahkdll)GetProcAddress(hinstLib, "ahkdll");
	
	if (ahkdll == NULL) 
	{
		printf("ERROR: unable to find DLL function\n");
		FreeLibrary(hinstLib);
		return 1;
	}
	
	// Call function.
	ahkdll_("D:\\MyScript.ahk", "", "");
 
	// Unload DLL file
	FreeLibrary(hinstLib);

	return 0;
}
But I keep getting this error :
The script file "D:\??????????????????k" does not exist. Create it now?

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
As it is Unicode you will need to pass wchar_t * :!:
#include <windows.h> 

#include <stdio.h> 

  



typedef int (*ahkdll)(wchar_t *, wchar_t *, wchar_t *) ; 

typedef int (*ahkReady)();



int main() 

{ 

    

   // Load DLL file 

   HINSTANCE hinstLib = LoadLibrary("AutoHotkey.dll"); 

   if (hinstLib == NULL) 

   { 

      printf("ERROR: unable to load DLL\n"); 

      return 1; 

   } 

    

   // Get function pointer 

   ahkdll ahkdll_ = (ahkdll)GetProcAddress(hinstLib, "ahkdll"); 

   ahkReady ahkReady_ = (ahkReady)GetProcAddress(hinstLib, "ahkReady"); 

    

   if (ahkdll_ == NULL || ahkReady_ == NULL) 

   { 

      printf("ERROR: unable to find DLL function\n"); 

      FreeLibrary(hinstLib); 

      return 1; 

   } 

    

   // Call function. 

   ahkdll_(L"D:\\MyScript.ahk", L"", L"");

   

   // Wait for script to finish

   while (ahkReady_())

	   Sleep(50);

   // Unload DLL file 

   FreeLibrary(hinstLib); 



   return 0; 

} 



HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Merged with AHK_L latest build
AutoHotkey_L49H8

basi
  • Members
  • 8 posts
  • Last active: Jan 11 2011 07:49 PM
  • Joined: 28 May 2007
It took me a while to figure out that HotkeyIt's versions was Unicode (as compared to Tinku99's version which is Ansi) . So I am posting the C# DLL Import prototype that worked for me, here.

C# prototype for the autohotkey.dll\ahkdll library call:
        [DllImport("AutoHotkey.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, EntryPoint = "ahkdll")]
        static extern int ahkdll([MarshalAs(UnmanagedType.LPWStr)] string scriptName,
           [MarshalAs(UnmanagedType.LPWStr)]string options,
           [MarshalAs(UnmanagedType.LPWStr)]string parameters);


Here is an Example of the C# prototype for the ahkFunction call:
        [DllImport("AutoHotkey.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, EntryPoint = "ahkFunction")]
        static extern string ahkFunction([MarshalAs(UnmanagedType.LPWStr)]string functionName,
           [MarshalAs(UnmanagedType.LPWStr)]string p1,
           [MarshalAs(UnmanagedType.LPWStr)]string p2,
           [MarshalAs(UnmanagedType.LPWStr)]string p3,
           [MarshalAs(UnmanagedType.LPWStr)]string p4,
           [MarshalAs(UnmanagedType.LPWStr)]string p5,
           [MarshalAs(UnmanagedType.LPWStr)]string p6,
           [MarshalAs(UnmanagedType.LPWStr)]string p7,
           [MarshalAs(UnmanagedType.LPWStr)]string p8,
           [MarshalAs(UnmanagedType.LPWStr)]string p9,
           [MarshalAs(UnmanagedType.LPWStr)]string p10);
         

Also don't forget to put the autohotkey.dll and your script (myscript.ahk) in the \bin\debug folder when you are testing/running from the C# IDE.

Thanks again HotkeyIT and Tinku99 for this DLL.

-Basi

BTW: Maybe the Docs should mention that tinku99 version is ANSI (and is easier to call/use with Chris's version of autohotkey.exe) and that HotkeyIts version is Unicode which is easier to use with Lexicos autohotkey.exe version....

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Merged with AHK_L latest build
+ Fix for DynaCall *pP parameter.
AutoHotkey_L50H9

elbeto
  • Members
  • 25 posts
  • Last active: Dec 14 2012 01:26 PM
  • Joined: 11 Apr 2010
Hello buddy ,first thanks for all your cool libraries hehehe I really enjoy to use it.

Now my question... well I´m trying to implement threads handlig using your autohotkey_test version and the ahkdllThread, now I can only implement dynamic threads using the tinku99 approach (mandelbrot) with this one you have to use the Filecopy function and other stuffs... Can you give a translation of the maldelbrot example using your auothotkey_test (dynacall and AhkDllThread)

I think is something like this one:

obj:=AhkDllThread(A_ScriptDir . "\AutoHotkeyMini.dll")
DynaCall(obj.ahktextdll,"&#Persistent`nMsgBox")

But I really do not know where to put the thread functionality (for example to draw the figure) can you give me a hand?

Thank you very much