Jump to content
Sign in to follow this  
packrat

AutoIt problem/bug with passing object arguments?

Recommended Posts

packrat

Using AutoIt, I need to be able to access the J language's powerful array features via OLE/COM, since I want to use AutoIt to essentially simultaneously access data in another Windows application at the same time. (Please note that I'm using AutoIt as a client to access a J server, not the other way around, which I know requires AutoItX.)

I am successfully able to connect to the J server (via its object) and to use both "Do" and "Set" methods to transfer commands and data to the J server. However, I seem unable to use the "DoR" method (a "get" type of method) to transfer data from the J server to a variable in my AutoIt script. Interestingly, I am able to do this transfer using VBScript, but I can't seem able to do it using AutoIt, leading me to believe that either there's some documentation missing on passing arguments in AutoIt or else there is perhaps a bug in AutoIt's implementation of objects and passing data through arguments.

Here's the VBScript code that works (see the AutoIt code below for comments):

' all VBScript variables are variants:
Dim j
Dim r
Dim Jversion
Dim A1
Dim A11

Set j = CreateObject("JEXEServer")
j.Quit
j.Do("0!:0 < 1!:45 ''")
j.Show(1)
j.Log(1)

ary = Array(1.1, 1.2, 1.3)

r = j.Set("A1", ary)

r = j.DoR("$ A1", A1)
WScript.Echo("$ A1: " & A1)

r = j.DoR("A1", A11)
WScript.Echo("A1: " & A11)

r = j.Do("jver =: 9!:14 ''")
r = j.DoR("jver", Jversion)
WScript.Echo("J version: " & Jversion)

Set j = Nothing
WScript.Echo("End")

Other than the "End" popup message window, the above code correctly produces three popup message windows indicating the progress of the script:

$A1: 3

A1: [boxed array containing 1.1 1.2 1.3]

J version: j601/2006-11-17/17:05

And here's the equivalent (and nearly exactly the same) AutoIt code (with comments) that doesn't work:

; all AutoIt variables are variants:
Global $j
Global $r
Global $Jversion
Global $ary[3]
Global $A1
Global $A11

$j = ObjCreate("JEXEServer") ; create the object for linking
$j.Quit ; set up J server to close automatically at end of script's object linkage
$j.Do("0!:0 < 1!:45 ''") ; load profile
$j.Show(1) ; show the J window
$j.Log(1) ; log the actions

$ary[0] = 1.1 ; set up simple array values
$ary[1] = 1.2
$ary[2] = 1.3

$r = $j.Set("A1", $ary) ; transfer the array to J variable "A1"

$r = $j.DoR("$ A1", $A1) ; transfer the J array "shape" to the AutoIt variable "$A1"
MsgBox(0,"","$ A1:" & $A1) ; display the $A1 variable's data

$r = $j.DoR("A1", $A11) ; transfer the J array to the AutoIt variable "$A11"
MsgBox(0,"","A1:" & $A11) ; display the $A11 variable's data

$r = $j.Do("jver =: 9!:14 ''") ; put the J version data into the J variable "jver"
$r = $j.DoR("jver", $Jversion) ; transfer the J "jver" data to the AutoIt variable $Jversion
MsgBox(0,"","J version: " & $Jversion) ; display the $Jversion variable's data

The above code produces three popup message windows with no values displayed:

$A1:

A1:

J version:

Both of these versions will cause the J server to display the following in a window:

$ A1
3
   A1
+-----------+
¦1.1¦1.2¦1.3¦
+-----------+
   jver =: 9!:14 ''
   jver
j601/2006-11-17/17:05

Let me mention at this point that the "DoR" method (I don't know if that stands for "Do Receive" or what) in the J server is the only "get"-style method that seems to work at all with VBScript and, hopefully, AutoIt, too. There are two other methods, "Get" (quite common) and "GetB" (a byte-oriented string variation?) that do not work, even though, as I said, "Get" is quite common in other applications, such as VB, Excel, etc. (I may be incorrect, but my guess is that "GetB" gets strings as arrays of bytes.) All three of these "get"-style methods have nearly the same syntax:

success = Jserverobj.DoR( Jcommand, AutoItvarname )

success = Jserverobj.Get( Jvarname, AutoItvarname )

success = Jserverobj.GetB( Jvarname, AutoItvarname )

Entering a variable's name in J displays the data in that variable, so the "DoR" method, even though it looks different (the Jcommand would be to type the Jvarname), has the same end result as the other two methods. Each method supposedly transfers the value in the specified J variable to the specified AutoIt variable. According to Microsoft's OLE/COM Object Viewer, here are excerpts from the J server related to the methods and associated arguments, in case this information is useful to you:

[id(0x60020011), helpstring("Execute string and return formatted output in BSTR.")]
long DoR(
                [in] BSTR input, 
                [out] VARIANT* v);

[id(0x60020006), helpstring("Get variant value from J variable.")]
long Get(
                [in] BSTR jname, 
                [out] VARIANT* v);

[id(0x6002000f), helpstring("Get variant value from J variable (BSTR).")]
long GetB(
                [in] BSTR jname, 
                [out] VARIANT* v);

I wish the "Get" and "GetB" methods would work in AutoIt (and VBScript), but they don't seem to.

Additionally, here's some information from some J documentation related to argument passing with VBScript (I presume it may apply to AutoIt as well):

VBScript only works with arrays of Variants, i.e., it does not support VT_ARRAY+VT_DOUBLE, only VT_ARRAY+VT_VARIANT. So each double needs to be "boxed", which exactly corresponds to J's boxed array. However, the array can be either nested (list of lists) or rectangular, i.e., Dim A(x,y,z,...). Get/Set and GetB/SetB are different in using byte array as opposed to BSTR for string type.

I will be immensely grateful to any and all responders who point me in the right direction, so that this AutoIt code can be made to work!

As I said, I don't know if I'm usng the arguments to objects incorrectly in AutoIt or if there's an argument bug in AutoIt when it comes to objects. I've worked with objects before in AutoIt (in terms of automating some Windows application or another), but, on the other hand, I've never needed to retrieve remote data into AutoIt variables like this. So all of this is brand new--and frustrating!--to me. Thanks in advance for any help and/or insights!

Harvey

------------------------------------------------------------

The powerful yet free J language (which you will need to understand and demo the problem) is available at Jsoftware. Utilizing only ASCII characters, it is derived from and is a successor language to APL. J was invented and developed by Ken Iverson (the inventor of APL) and Roger Hui.

For purposes of my question, all you need to do is download and install the language, and then execute the jreg.bat file in the same folder where you installed J. (This batch file registers the two J servers, JEXEServer and JDLLServer, so that you can access these objects. The EXE server displays what is happening in a window, whereas the DLL server is windowless.) Then start up the J interpreter initially to display a welcome splash window that you need to turn off via checkmark for subsequent uses and close the interpreter. Finally, just run the above VBScript and AutoIt scripts to see what happens.

------------------------------------------------------------

Additional keywords for searching this message in the future (since "J" is an unsearchable single character in forums):

Jay language

Jlanguage

Jsoftware

Jserver

Share this post


Link to post
Share on other sites
PsaltyDS

I don't have J server to play with, so I can't test the truthiness of this, but COM object property assignment looks like this:

$j.Do ("0!:0 < 1!:45 ''") ; load profile
$j.Show = 1 ; show the J window
$j.Log = 1 ; log the actions

The first of those lines calls a method with a string input parameter, but the next two looked more to me like property value assignments.

:D


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites
packrat

I don't have J server to play with,

Just download and install it--it's free and installs in only a minute or two, as I recall. (It's a complete programming language with IDE, but its programming is at a higher level of abstraction than nearly all procedural languages, which can make it both easier and harder to learn. Much of the looping code we're familiar with (particularly in dealing with lists, arrays, matrices, tables, etc.) is automatically incorporated in primitives, which can make J code extremely compact compared to AutoIt, C, VB, etc. I'm a very "neo" neophyte with J, but it's better able to deal with certain data than I can in other languages, which is why I'm trying to use AutoIt as my "master control language" for interfacing to other languages via their exposed objects.)

so I can't test the truthiness of this, but COM object property assignment looks like this:

$j.Do ("0!:0 < 1!:45 ''") ; load profile
$j.Show = 1 ; show the J window
$j.Log = 1 ; log the actions

The first of those lines calls a method with a string input parameter, but the next two looked more to me like property value assignments. :D

Yes, it may look that way, but "Show" and "Log" here are object methods not object properties. Here are the definitions of the J server object's methods for the three statements you highlighted above, using Microsoft's OLE/COM Object Viewer (I thought I'd include the methods for "Set" as well, since I showed the complementary "Get" methods in my original message):

[id(0x60020000), helpstring("Execute string.")]
long Do([in] BSTR input);

[id(0x60020001), helpstring("Show (1) or hide (0) J EXE Server.")]
long Show([in] long b);

[id(0x60020002), helpstring("Display (1) or discard (0) J EXE Server session manager input and output.")]
long Log([in] long b);



[id(0x60020007), helpstring("Set variant value in J variable.")]
long Set(
                [in] BSTR jname, 
                [in] VARIANT* v);

[id(0x60020010), helpstring("Set variant value in J variable (BSTR).")]
long SetB(
                [in] BSTR jname, 
                [in] VARIANT* v);

By the way, both the "Show" and "Log" methods must be included and enabled (value=1) in AutoIt code when accessing the JEXEserver object; otherwise, you won't see a window or anything happening in the window. (On the other hand, they should be omitted when accessing the JDLLserver object instead, which processes commands and data without a window. This is how I will eventually use the OLE/COM connection, but I need to see the window for testing purposes initially.)

Harvey

Share this post


Link to post
Share on other sites
packrat

I neglected to include some further information from the AutoIt documentation--in the help topic "COM Extensions to AutoIt" (which is found under "Obj/COM Reference" in the help index), the section "Limitations on COM Events in AutoIt" states:

AutoIt uses its own variable scheme, which is not compatible to COM variables. This means that all values from Objects need to be converted into AutoIt variables, thus losing the reference to the original memory space. Maybe in the near future we can solve this limitation for you!

My questions related to this:

(1) What does all this mean in practical terms?

(2) Exactly how does one convert "values from Objects" into "AutoIt variables"?

(3) The last sentence has been there a while--any idea of when "in the near future" this limitation will be resolved?

In looking at these sentences more carefully, perhaps this might be what's at the core of my original query--in terms of why data from an object is not ending up properly in my AutoIt variables. As I said, I have no problem sending data to this particular object; my problem is in receiving data from the object. Thanks again for any help in this regard!

Harvey

Share this post


Link to post
Share on other sites
packrat

In the help topic "COM Extensions to AutoIt" (which is found under "Obj/COM Reference" in the help index), the section "Limitations on COM Events in AutoIt" states:

AutoIt uses its own variable scheme, which is not compatible to COM variables. This means that all values from Objects need to be converted into AutoIt variables, thus losing the reference to the original memory space. Maybe in the near future we can solve this limitation for you!

This paragraph hasn't changed since previous versions of AutoIt3. Is this "limitation" ever going to get fixed?? "In the near future" is beginning to sound like "Real Soon Now". I have applications that are waiting on this fix. Thanks!

Harvey

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.