Linguist Posted November 16, 2014 Share Posted November 16, 2014 Hallo dear buffs, by scripting a data driven KodaForm (.kxf) compiler with and for AutoIt, I stumbled across an unexplained problem with the special CallArgArray option of the AutoIt Call function that needs a short explanation. As the documentation says, "This array must have its first element set to "CallArgArray" and elements 1 - n will be passed as separate arguments to the function.", it causes an odd inconvenience if the array (according to to the called function) has no further arguments exept the keyword "CallArgArray". Is this intended, or grounded in the inner workings of AutoIt? For me it's an extra step in the loop to check such situation and reduces the performance unnecessarily. Any savvy would be appriciated, as well as an advice to open a bug report or a feature request. Link to comment Share on other sites More sharing options...
Developers Jos Posted November 16, 2014 Developers Share Posted November 16, 2014 Not sure what the issue is and why use call() at all? Can you show a snippet showing your issue? Jos SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
Linguist Posted November 16, 2014 Author Share Posted November 16, 2014 Hey Jos, that was quick. Thanx! Here's a short snippet: local $aCallArg1[]=["CallArgArray",10,8],$aCallArg2[]=["CallArgArray"] MsgBox(default,"Probe 1","0x"&Call("Hex",$aCallArg1)&@LF&Hex(@error,4)&" "&Hex(@extended,4)) exit MsgBox(default,"Probe 2",Call("_ReturnIt",$aCallArg2)&@LF&Hex(@error,4)&" "&Hex(@extended,4)) func _ReturnIt() return 100 endfunc Link to comment Share on other sites More sharing options...
Developers Jos Posted November 16, 2014 Developers Share Posted November 16, 2014 (edited) What about something like this: Global $aCallArg1[] = ["CallArgArray", 10, 8] Global $aCallArg2[] = ["CallArgArray"] ConsoleWrite("Probe 1 0x" & Call("_ReturnIt", $aCallArg1) & @CRLF & @error & " " & @extended & @CRLF) ConsoleWrite("Probe 2 " & Call("_ReturnIt", $aCallArg2) & @CRLF & @error & " " & @extended & @CRLF) Func _ReturnIt($Param1 = 1, $Param2 = 1) Return $Param1 * $Param2 EndFunc ;==>_ReturnIt Jos Edited November 16, 2014 by Jos SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
Linguist Posted November 16, 2014 Author Share Posted November 16, 2014 Thanks for your suggestion, but my problem is more general. The used Hex function is just an example, as well as the _returnIt UDF. By scripting a data driven program code the Call function is the only point of intersection between DATA and CODE and acts as my 'von Neumann Gate' , cos no other function is able to take an ASCII string and make it a function call. If the loop has to decide (on the data given) which AutoIt function (or UDF) is to be used to prosess them, its next task is to assemble an CallArgArray. But if the loop decides to call a function w/o an argument, it stucks. This is the reason why it has to switch to another Call function call with no arguments at all. That comes undhandy! If I could use an 'empty' CallArgArray in the same way Call is processed w/o arguments, things would be a bit easier. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted November 18, 2014 Moderators Share Posted November 18, 2014 Linguist,I have been thinking about this problem and, while you have highlighted the case where the function takes no parameters, it also arises when you do not pass sufficient parameters to a function where the parameters have no default value set:#include <MsgBoxConstants.au3> Local $aCallArg2[] = ["CallArgArray", 10, 8], $aCallArg1[] = ["CallArgArray", 10], $aCallArg0[] = ["CallArgArray"] MsgBox($MB_SYSTEMMODAL, "2/2 Params", Call("_ReturnIt_2", $aCallArg2) & @LF & Hex(@error, 4) & " " & Hex(@extended, 4)) MsgBox($MB_SYSTEMMODAL, "1/2 Params", Call("_ReturnIt_2", $aCallArg1) & @LF & Hex(@error, 4) & " " & Hex(@extended, 4)) MsgBox($MB_SYSTEMMODAL, "0/2 Params", Call("_ReturnIt_2", $aCallArg0) & @LF & Hex(@error, 4) & " " & Hex(@extended, 4)) MsgBox($MB_SYSTEMMODAL, "2/0 Params", Call("_ReturnIt_0", $aCallArg2) & @LF & Hex(@error, 4) & " " & Hex(@extended, 4)) MsgBox($MB_SYSTEMMODAL, "1/0 Params", Call("_ReturnIt_0", $aCallArg1) & @LF & Hex(@error, 4) & " " & Hex(@extended, 4)) MsgBox($MB_SYSTEMMODAL, "0/0 Params", Call("_ReturnIt_0", $aCallArg0) & @LF & Hex(@error, 4) & " " & Hex(@extended, 4)) Func _ReturnIt_2($vParam1, $vParam2) Return "Any problem with 2 params?" EndFunc ;==>_ReturnIt Func _ReturnIt_0() Return "Any problem with no params?" EndFunc ;==>_ReturnItSo the problem is not really AutoIt failing to deal with an "empty" CallArgArray array, but that any such array which does not correctly match its elements to the function's obligatory parameters will fail. This I see more as a restriction on the coder than an AutoIt problem per se. AutoIt cannot read your mind and it is the coder's responsibility to provide the correct parameters for any function they use. I fear that you may well have to store a value for each of the functions that could be called giving the number of obligatory parameters needed. Then you can correctly size your CallArgArray array for that particular function. If you store these functions names in an array, could you not add another column to hold such a value? M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
Linguist Posted November 18, 2014 Author Share Posted November 18, 2014 Melba23, thanx a lot for your thoughts and your explanation. I have to agree that this is not realy an AutoIt failure, as the Call documentation states in particular "elements 1 - n will be passed" and no argument would be a zero. You are also right about the fact that the scribe is responsible for the number of arguments within the array. Never the less, if the called function intakes no arrguments at all, an 'empty' CallArgArray reflects the correct number. Since the only AutoIt function (as far as I know) w/o an argument is SplashOff() this problem concerns first and foremost an UDF call. In the end it's probably just a question of symetry, to treat an 'empty' CallArgArray like a Call function call w/o arguments. To circumvent this obstacle, is of course just a tenary operation like: $var=(Ubound($aCallArg)>1 ? Call("func",$aCallArg) : Call("func")) Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted November 18, 2014 Moderators Share Posted November 18, 2014 Ternary is certainly an option, or you could wrap your Call function in a custom function that validates what you need it too without changing the style of your code/coding. Something like this maybe: Func _myCustomCall($s_func, $v_p1 = "", $v_p2 = "", _ $v_p3 = "", $v_p4 = "", $v_p5 = "", $v_p6 = "", _ $v_p7 = "", $v_p8 = "", $v_p9 = "", $v_p10 = "", _ $v_p11 = "", $v_p12 = "", $v_p13 = "", $v_p14 = "", _ $v_p15 = "", $v_p16 = "", $v_p17 = "", $v_p18 = "", _ $v_p19 = "", $v_p20 = "") ; obviously could add more, but 21 params is crazy anyway Local $v_ret = 0, $a_callargs = $v_p1 If Not IsArray($a_callargs) Then Dim $a_callargs[@NumParams] $a_callargs[0] = "CallArgArray" For $i = 1 To UBound($a_callargs) - 1 $a_callargs[$i] &= Eval("v_p" & $i) Next EndIf Switch UBound($a_callargs) Case 1 $v_ret = Call($s_func) Case Else $v_ret = Call($s_func, $a_callargs) EndSwitch Return SetError(@error, @extended, $v_ret) EndFunc Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Linguist Posted November 18, 2014 Author Share Posted November 18, 2014 SmOke_N, good thinking and there are at least 'fifty ways to love your liver' but my main concern (as mentioned above) is the lack of performance. Coding a script language means @1st 'cause to make' not doing scripting epics. On the other hand, if coding a data driven script I have to consider every called function as a blackbox with none of my hands inside. So I leave it up to you (as 'guardians of the AutoIt galaxy') to make the posed oddity a feature request for isometry, or let the sufficient afflicted scribe deal with it. Anyway... Thanx for your attention. Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted November 18, 2014 Moderators Share Posted November 18, 2014 I didn't disagree with your first post. I was merely offering an alternative to the issue at hand. I think the melodramatics are a bit much when referring to "every called function". You're playing with dynamic structuring, with one of the only few functions that will allow it. If you did have to consider it, it would be with your design and with only those functions that allow dynamic data implementation. Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Gianni Posted November 18, 2014 Share Posted November 18, 2014 maybe a "safe" way to use the Call() function with the "CallArgArray" special array is like this: 1) prepare an array with as many parameters as you like to pass (also arrays within array, or just an empty variable as well) 2 call your function by passing your parameters contained in the above array in this way; $aSendArguments[2] = ["CallArgArray", $aMy_Args] perhaps in this way the call() function should never fail Local $aMy_Args[] = [1, 2, 3, "four"] ; pass 4 arguments for example (or more...) Local $aSendArguments[2] = ["CallArgArray", $aMy_Args] ; prepare the Packet containing arguments Call("MyBlackBoxFunction", $aSendArguments) Local $aMy_Args = "" ; pass nothing Local $aSendArguments[2] = ["CallArgArray", $aMy_Args] ; prepare the Packet containing arguments Call("MyBlackBoxFunction", $aSendArguments) Func MyBlackBoxFunction($aArguments) MsgBox(0, "", "Received " & UBound($aArguments) & " arguments") ; manage the arguments received within the $aArguments array EndFunc ;==>MyBlackBoxFunction Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
Linguist Posted November 18, 2014 Author Share Posted November 18, 2014 SmOke_N, I didn't ment to be melodramtic nor rude and I really do appreciate your help, honestly. For me 'Scripting epics' is a more general tern and wasn't refering to your helping code example at all, which is of course a possible solution. Sorry it came over this way! My hope is, that a tiny improvement within the AutoIt Call function would improve the core loop performance of my DATA-CODE intersection. Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted November 18, 2014 Moderators Share Posted November 18, 2014 SmOke_N, I didn't ment to be melodramtic nor rude and I really do appreciate your help, honestly. For me 'Scripting epics' is a more general tern and wasn't refering to your helping code example at all, which is of course a possible solution. Sorry it came over this way! My hope is, that a tiny improvement within the AutoIt Call function would improve the core loop performance of my DATA-CODE intersection. Understood, I wasn't referring to my code either. I understand your wish for it to be improved upon, and have to agree. Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Linguist Posted November 19, 2014 Author Share Posted November 19, 2014 Thanx SmOke_N and Chimp, I know, I'm a strange guy with silly problems... Why would anyone being so eager with one of the most unused AutoIt features? So please allow me to give a more sprawling tour and turn from abstract to concrete, beginning with the key question: An own KodaForm (.kxf) compiler, really?! By this time I'm scripting nearly 5 years with AutoIt and I love it, cos it's one of the fastest and most versatile scripting engines for Windows. Since then I coded lots of applications for several social constitutions and for companies and out of a simple automation & admin-tool coding, things are grown up to full blown custom projects, usually done with C++ before. One of my everyday problems (besides keeping OCX modules on the hop) is to tailor GUI scripts and meanwhile this task is getting real ugly if you have to design an application with hundreds of GUI controls. Therefore I decided fiddle a completely new approach (avoiding WPF) and started to compile KXF files into a SQLite database. Although this compiler prototype is coded in AutoIt by now, it will be done with C++ later on (or even with FASM if it fits my needs), but when it comes to the AutoIt application, I have to stick with the scripting engine. Key element of the AutoIt source include for my applications is a tiny wrapper as a resource loader, based on a SQL COM object and has to deliver (among icons, pics and other GUI control data) my so called 'FormCode' records. Their simple SQL table format looks like: [FormName, SegmentName, OrdinalNum, ObjectName, ObjectTag, FormCode] The FormCode itself is a pipe delimited ASCII String and starts with a function name (AutoIt function, or UDF) followed by a bunch of pre-evaluated data and/or 'EvalClauses'. Such an EvalClause is an unevaluated param and itself a function, too, preceded with a suitable PrefixToken (§Function, @Macro, or $Variant). This funny FormCode string looks like e.g.: "GUICtrlSetBkColor|$MyControlID|§_WinAPI_GetSysColor;15" If the runtime UDF is going to open a new Form (actual with _GUICreate("FormName") ) it simply issues a SQL statemant and gets back a statement object with all FormCode records of the given FormName. Than it has to step thru this object taking one FormCode after the other (sorted by their OrdinalNum) and has to evaluate all its given EvalClauses. This is the first time the AutoIt Call function come into play (or the Execute function, if an @ or $ token is indicated). This has to be done once for every given GUI function param (with its own temporary CallArgArray). In the end it returns a ready-made GUI function CallArgArray, which is used by the final Call function call. Lets say a GUI function Call has to be evaluated with 3 EvalClauses per Call (on average) and a complete GUI form has e.g. 40 FormCode records (building steps), it has to process 120 Call function calls all in all. That's where my life comes to 'zen of code optimiziation' and my part of the job, is to reduce every loop to its absolut minimum to make this tricky concept work on a scripting engine. I hope this could somehow clarify my hardships at least a bit and I'd be pleased if ever anyone was following my tour up to this point. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted November 19, 2014 Moderators Share Posted November 19, 2014 Linguist,Interesting concept - delighted you are coding it and not I ! The use of a prefix character to identify the use of the following string reminds me of an old DOS menu app that I wrote some 25 years back which read lines from inifiles and used similar prefix characters to determine whether the line was for display or what to do once a selection was made. But as you already use these prefixes to distinguish between using Call / Execute on the string, can you not simply add another prefix to make a similar distinction between Call / Call /w CallArgArray? You must already do a test on the string to differentiate the leading character so you would not be further slowing the overall process, just adding another Case to whatever decision structure you use. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
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