AutoHotkey Community

It is currently May 26th, 2012, 9:15 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 563 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6 ... 38  Next
Author Message
 Post subject: Revision 0.69
PostPosted: May 17th, 2009, 8:23 pm 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
V0.7 re-enabled Reload command. (the hosting application restarts with the client A_ScriptName as the command line parameter)

Experimental: Exported Functions for many Commands, BIV: Examples

Edit:
I have disabled the exported Commands for now, will add them when they are more robust.


Last edited by tinku99 on June 5th, 2009, 5:06 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject: Revision 7
PostPosted: June 5th, 2009, 4:54 am 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
Revision 7

* Merged with AutoHotkey v.1.0.48.03_L30
* in addition to AutoHotkey.dll, created AutoHotkey_N.exe with
* exported functions to access built in variables: ebiv.cpp
* added function:
* linepointer = Import(filename, aAllowDuplicateInclude = false, aIgnoreLoadFailure = false).
* linepointer is a pointer to the first line in the imported script
* If the 3rd parameter is > 1, then all currently loaded lines, functions, and labels are ignored starting now.
* If you are going to reload particular hotkeys, use the Hotkey command rather than Hotkey labels.
* i.e.
* Hotkey, F2, mylabel, on ; this can be repeated in future import(script) calls
* not
* F2::msgbox ; this will crash the script if you import another script that uses the same hotkey label


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 5th, 2009, 3:35 pm 
Offline

Joined: May 28th, 2007, 4:09 pm
Posts: 8
Just wanted to let you know that some of us have been playing around with this.

For my purposes I am trying to call Autohotkey.dll from C#. I have been able to call the DLL and have it run a script. But AFTER the script runs it always crashes C#. Idealistically, I would just like the Autohotkey.dll to expose the commands/functions built into AHK, so that I could call them directly from C#. No biggy, just playing around.

Thank you for continuing to develope your DLL.


-Basi

P.S. Haven't tried IronAHK but will look into it.


Report this post
Top
 Profile  
Reply with quote  
 Post subject: c sharp
PostPosted: June 5th, 2009, 3:55 pm 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
Basi, thanks for the feedback.
basi wrote:
AFTER the script runs it always crashes C#.
Have you tried to make the script persistent? with: #Persistent
Clean unloading of the dll is on my todo list, but low priority.
If you just want to reload a different script into the application, you can do that with the new builtin Import() function. I will add that functionality in the exported addfile() function also.
Quote:
I would just like the Autohotkey.dll to expose the commands/functions built into AHK
Which commands and functions are you most interested in seeing libyfied?


Report this post
Top
 Profile  
Reply with quote  
PostPosted: June 18th, 2009, 9:34 pm 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
I modified numget and numput to take numerical arguments for type in addition to the dllcall types. (number != dlltypesize)
also modified variable assignments to preserve binary data by copying varCapacity instead of varLength.

It would be nice if argstruct and dereftype used varcapacity instead of stringlength as well, but i don't know what depends on this.

also, i compiled the machine code functions from lexikos' lowlevel as BIF's also.

AutoHotkey_N.exe
source
Example:
Code:
varsetcapacity(a, 10000, 0)
a = a
element = element%A_Index%
numput("element0", a, 0, 10)
loop, 10
{
element = element%A_Index%
numput(element, a, 10 * A_Index, 10)
}

msgbox % a
loop, 10
{
ListVars
msgbox % el := numget(a, 10 * A_Index, 10)
}
return


Report this post
Top
 Profile  
Reply with quote  
PostPosted: June 20th, 2009, 7:18 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
tinku99 wrote:
also modified variable assignments to preserve binary data by copying varCapacity instead of varLength.
That is likely to have an adverse effect on performance of some scripts - i.e. when the source variable's capacity is much greater than the length of the meaningful data. Simple assignments can already copy null characters if you do not update the length. For instance:
Code:
VarSetCapacity(n,4,1) ; 4 non-zero bytes
NumPut(0,n)
m := n
MsgBox % "n: '" n "'`nm: '" m "'`nStrLen(m): " StrLen(m)
Rather than unconditionally copying all data (meaningful or not), you could implement VarSetLength() and let the script define how much data is meaningful and therefore should be copied.
Quote:
It would be nice if argstruct and dereftype used varcapacity instead of stringlength as well,
I strongly disagree. Copying beyond the length (and beyond null characters) where a string is expected would not only break the majority of scripts (where data beyond length is meaningless), but would be utterly unintuitive. That brings me to my next point...
Quote:
numput("element0", a, 0, 10)
I have to ask... why??? You can easily DllCall lstrcpyn or RtlMoveMemory.


Report this post
Top
 Profile  
Reply with quote  
PostPosted: June 20th, 2009, 2:35 pm 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
Lexikos wrote:
That is likely to have an adverse effect on performance of some scripts -...you could implement VarSetLength() and let the script define how much data is meaningful and therefore should be copied.

VarCapacity only exceeds VarStringLength significantly when you have set the capacity high yourself, with VarSetCapacity, which to me serves the purpose of VarSetLength. How about a flag for string vs. binary data? Binary data would get copied by capacity, string data by string length...
Lexikos wrote:
Copying beyond the length (and beyond null characters) where a string is expected would not only break the majority of scripts (where data beyond length is meaningless), but would be utterly unintuitive.
Well, I definitely don't want to break any existing scripts. Will think about its implications some more. IMO, what is unintuitive is:
Code:
VarSetCapacity(x, 100, 88)
x = aaaaaaaaasdfs ; some data
numput(0, x, 80, "char")
copyx := x 
if (numget(x, 85) != numget(copyx, 85))
Msgbox copyx is not the same as x beyond byte element 80. 

x = aaaaaaaaasdfsaaaaaaaaaaaaaaaaaa ; some data
numput(0, x, 10, "char")
copyx := x 
if (numget(x, 15) == numget(copyx, 15))
Msgbox copyx is the same as x beyond byte element 10 for (varsize < 64)
Lexikos wrote:
Quote:
numput("element0", a, 0, 10)
I have to ask... why??? You can easily DllCall lstrcpyn or RtlMoveMemory.
for the same reasons as having numput in the first place. The current limitations on numput are unnecessary. Also, isn't numput faster than a dllcall?

By the way, I think i have an idea of how to reset the memory of the script. I can just step through the linked list of simpleheaps, and free them all. Then I can load a whole new script using the bif Import() or exported addfile()... without most of the memory leak.

Also, I am thinking of modifying and exporting the command: Hotkey to take function names and function pointers in addition to labels. Something like:
Code:
void Hotkey::PerformInNewThreadMadeByCaller(HotkeyVariant &aVariant){
...
  if aVariant.mJumpToLabel
   ResultType result = aVariant.mJumpToLabel->Execute();
  if aVariant.mHotFunc
   {
     char returnValue[64];
     Func *hotfunc = g_script.FindFunc(aVariant.mHotFunc);
     hotfunc->Call(returnValue);
   }
  if aVariant.mFunctionPointer
{
   (*aVariant.mFunctionPointer)(aVariant);  // optionally in an os thread
}
}


Report this post
Top
 Profile  
Reply with quote  
PostPosted: June 20th, 2009, 3:29 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
tinku99 wrote:
VarCapacity only exceeds VarStringLength significantly when you have set the capacity high yourself, with VarSetCapacity,
Really? :roll:
Code:
Loop, 50
    var .= "VarSetCapacity isn't the only way to expand a variable. "
var := "abc"
MsgBox % VarSetCapacity(var)
Not the most practical example, but hopefully you get my point.
Quote:
which to me serves the purpose of VarSetLength.
The capacity of a variable is by definition the amount of data it can contain (not necessarily the amount it does contain), regardless of how VarSetCapacity is most commonly used.
Quote:
How about a flag for string vs. binary data? Binary data would get copied by capacity, string data by string length...
What if binary data may be variable length, and we want the variable to be able to hold more binary data than it currently holds? Flagging the variable as "binary or not" does not allow for this; VarSetLength() does.
Quote:
IMO, what is unintuitive is:
I don't see why you expect meaningless garbage to be copied, especially when you've assigned a string. (I know it's "just" an example...)
Quote:
for the same reasons as having numput in the first place.
I think you missed my point. Num is short for NUMBER. A (non-numeric) string is not a number. If you were to create a built-in function for copying strings and give it a more logical name, I would not object.
Quote:
By the way, I think i have an idea of how to reset the memory of the script.
Careful. Some structures use dynamic memory (e.g. Func::mVar). Some other global structures must be re-initialized.
Quote:
The current limitations on numput are unnecessary.
The current limitations are intuitive.
Quote:
Also, I am thinking of modifying and exporting the command: Hotkey to take function names and function pointers in addition to labels.
Sounds useful.


Report this post
Top
 Profile  
Reply with quote  
PostPosted: June 21st, 2009, 9:27 am 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
var := binaryVar
was causing problems, have removed this buggy feature for now.

Will use a new BIF called move or copy instead of numput as lexikos suggests.


Report this post
Top
 Profile  
Reply with quote  
PostPosted: June 25th, 2009, 9:40 pm 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
Changes in ahkdll9:
modified fileappend, to send output to stderr, with "stderr" is specified as filename. then do:
Code:
FileAppend, errors, stderr
...
> autohotkey.exe script.ahk 2> error.log 

modified FileReadLine, to accept stdin for file
Code:
FileReadLine, line1, stdin, 1
FileReadLine, line2, stdin, 1
listvars
msgbox
...
> type script.ahk | autohotkey.exe script.ahk

example filter program:
pipes.exepipes.ahk
AutoHotkeySC.bin


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 20th, 2009, 10:14 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Hi tinku99, I have played a little around with AutoHotkey_N.exe and AutoHotkey.dll.

Tried the function import() but it does not return the line_ptr but a character, which differs from file to file? Is it a bug?
Code:
line_ptr:=Import("x:\test1.ahk")
MsgBox % line_ptr

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 20th, 2009, 10:55 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Hi tinku99,

Thank you so much for multithreading feature, its just great :D
This is exactly what i have been asking around a while ago. I already thought this is not going to happen :o
Hopefully it will be possible to unload the dll so memory gets freed and a file can be reloaded. :?:

Is there a way to include that functionality/function into AutoHotkey_N.exe so dll would not be required at all?

I found out that you can load different dlls just by renaming them so copying is not required :D
I have created a function for this so you can run as many threads as you like.
Thread() - Based on AutoHotkey.dll wrote:
- Thread(file,parameters,dll)
- - file can be a file or text/variable containing script
- - parameters to pass to file
- - AutoHotkey.dll location

:!: Currently it is required to include #Persistent in your script and you cannot load same file again


Press F1, F2 or F3 to run the file (if exist) or F4 or F5 to run variable script
Mandelbrot*.ahk
Code:
#Persistent
AHKfile1=%A_ScriptDir%\mandelbrot1.ahk
AHKfile2=%A_ScriptDir%\mandelbrot2.ahk
AHKfile3=%A_ScriptDir%\mandelbrot3.ahk
Return

!r::Reload
!q::ExitApp

F1::
F2::
F3::
file:="AHKfile" . SubStr(A_ThisHotkey,0)
Thread(%file%)
return
F4::
Script=
(
#Persistent
#NoEnv
#NoTrayIcon
Loop
   ToolTip `% A_Now "``n" A_TickCount,0,0
)
Thread(script)
Return
F5::
Script=
(
#Persistent
#NoEnv
#NoTrayIcon
Loop
   ToolTip `% A_Now "``n" A_TickCount,0,50
)
Thread:=Thread(script)
Return



Thread(file="",parameters="",dll="AutoHotkey.dll"){
   static thread, ahkdll, file_check
   If (!FileExist(dll))
      Return false
   isfile=0
   Loop %file%
      If (InStr(file_check,"|" . A_LoopFileFullPath . "|") or (file_check.=("|" . A_LoopFileFullPath . "|") and !(isfile:=1)))
         Return false
   thread:="AutoHotkey_" A_TickCount . ".dll"
   FileMove, %dll%, %thread%
   lib:=DllCall("LoadLibrary", "str", thread)
   FileMove, %thread%,%dll%
   If (!isfile){
      #__PIPE_NAME_ := A_TickCount
      #__PIPE_GA_ := DllCall("CreateNamedPipe","str","\\.\pipe" #__PIPE_NAME_,"uint"
                     ,2,"uint",0,"uint",255,"uint",0,"uint",0,"uint",0,"uint",0)
      #__PIPE_    := DllCall("CreateNamedPipe","str","\\.\pipe" #__PIPE_NAME_,"uint"
                     ,2,"uint",0,"uint",255,"uint",0,"uint",0,"uint",0,"uint",0)
      if (#__PIPE_=-1 or #__PIPE_GA_=-1) {
         MsgBox CreateNamedPipe failed.
         Return
      }
      thread_ := DllCall(thread . "\ahkdll", "str", "\\.\pipe" . #__PIPE_NAME_, "str"
                           , "", "str", parameters, "Cdecl Int")
      DllCall("ConnectNamedPipe","uint",#__PIPE_GA_,"uint",0)
      DllCall("CloseHandle","uint",#__PIPE_GA_)
      DllCall("ConnectNamedPipe","uint",#__PIPE_,"uint",0)
   } else
      thread_ := DllCall(thread . "\ahkdll", "str", file, "str", "", "str", parameters, "Cdecl Int")
   If (!isfile){
      file := chr(239) . chr(187) . chr(191) . file
      if !DllCall("WriteFile","uint",#__PIPE_,"str",file,"uint",StrLen(file)+1,"uint*",0,"uint",0)
         MsgBox WriteFile failed: %ErrorLevel%/%A_LastError%
      DllCall("CloseHandle","uint",#__PIPE_)
   }
   ErrorLevel:=lib
   Return thread_
}

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Last edited by HotKeyIt on July 21st, 2009, 7:29 pm, edited 3 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject: pointer from import()
PostPosted: July 20th, 2009, 11:55 pm 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
I wouldn't worry about the pointer or char too much.
The code imported is already byte compiled.
You can start running functions imported dynamically without doing anything else...

I had a plan for clearing the loaded script and its memory, but I won't get to it soon unfortunately.


Report this post
Top
 Profile  
Reply with quote  
PostPosted: July 21st, 2009, 5:54 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
tinku99 wrote:
I wouldn't worry about the pointer or char too much.
The code imported is already byte compiled.
You can start running functions imported dynamically without doing anything else...

It would be nice if a pointer would be returned :)
Is it feasible to import text instead of a file as well?

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
PostPosted: July 27th, 2009, 6:57 am 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
HotKeyIt wrote:
It would be nice if a pointer would be returned :)
Is it feasible to import text instead of a file as well?

You were right, there was a bug.
Now Import also returns a pointer just like addfile.
Importing text is possible, but will require some changes to addfile.
Will add it to list of things to do. Until then, you can load text through a named pipe.

To use lowlevel with AutoHotkey_N or AutoHotkey.dll make the following changes to LowLevel instead of using LowLevel_Init():
Code:
; Replaced mcode functions with builtin functions
__static(var) {
return static(var)
}
__getVar(var) {
return getVar(var)
}
__alias(alias, alias_for) {
return alias(alias, alias_for)
}
__cacheEnable(var) {
return cacheEnable(var)
}
__getTokenValue(token) {
return getTokenValue(token)
}
/*
myLowLevel_init() {
    __init()
}

__init() {
    Global
    ; __getFirstFunc must be called at least once before (or by) __mcode, or it won't work properly later on.
    __getFirstFunc()
    __mcode("__getVar","8B4C24088B0933C08379080375028B018B4C2404998901895104C3")
    __mcode("__static","8B4424088B008378080375068B0080481504C3")
    __mcode("__alias","8B4C24088B01837808038B4904751D8B51088B005633F64A74044A4A75028B3185F60F94C189700C8848175EC3")
    __mcode("__cacheEnable","8B4424088B0083780803750F8B008078170075038B400C8060157FC3")
    __mcode("__getTokenValue","8B4424088B0083780801752B8B008B500883FA0375108B008A481580E13074180FB6D1C1EA048B4C24048951088B1089118B4004894104C38B4C2404C74108040000008B40088901C3")
    __mcode("__init","C3"), __mcode("LowLevel_init","C3") ; C3 = RET
}
*/


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 563 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6 ... 38  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 3 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group