Jump to content

Recommended Posts

Posted (edited)

I intuitively thought thatafter return, the correspondig memory area would show this data.

As the result of call this function you won't really work with this string, you pass to function a pointer to your string, your function made all changes in the memory location (here are stored you string) indicated by this pointer. As the result of dll call in first index (0 index) all time is returned the result (in your case an integer that represent the version in a numeric form) that has nothing to do with your string, and all other indexes are parameters passed to called function (you have just one, the pointer to your string). This is why dll call does not return any string but a pointer to your string.

To respond your question: you don't really need know where this data are (somewhere in memory) as long you can access this data through its pointer.

Edited by Andreik
Posted

...

@Martin:

Thank you for your hint with Delphi.. I'll tell you a bit more about the usage of.....

Ok, I see my example was not useful in that case.

@Andreik:

Ok. I see. But there remains a question: Where is my data going ? In my DLL function, y write the string "KGF.dll V01.90 28/12/2012", byte by byte, into the memory pointed by the first (and only) parameter of the function. I intuitively thought thatafter return, the correspondig memory area would show this data.

It does show the data in the corresponding memory area when I run the script and use your dll.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Posted (edited)

To respond your question: you don't really need know where this data are (somewhere in memory) as long you can access this data through its pointer.

But that's exactely the problem ! i do know where the initial data is - it's the copy of the string which has been inserted into the structure. I know, this is different from my variable, but that's ok.

Now, I pass the address to this copy of string to my DLL function. Within this function, I should be able tu acces these data bytes using the passed address, both for read and write ! There is no error message, but trying to write at this address does not change the data at the specified location ! The following code shows this:

$sver = "1234567890123456789012345"

MsgBox(0,"","Initial pointer: " & DllStructGetPtr($stString))

$ver = DllCall($dll, "int", "KGFdllVersion", "ptr*", DllStructGetPtr($stString))

#cs

$ver[0] - contain returned int value of your function

$ver[1] - is the pointer of the structure (so cannot be something meaningfull for you but for application yes)

Your data is located in the structure that starts where this pointer say.

Here is not changed $sver variable.

#ce

MsgBox(0,"","Return value: " & $ver[0] & @CRLF _

& "Structure pointer: " & $ver[1] & @CRLF _

& "Data from structure: " & DllStructGetData($stString,"v") & @CRLF _

& "Data from structure: " & DllStructGetData($stString,1))

DllClose($dll)

After DllCall, the data should be:KGF.dll V01.90 28/12/2012. My feeling is that not only the parameters are copied to the array $ver, but the structure is duplicated too, and the element [1] of the result array points into the copied area and not into the original one, where my text bytes have been written ! Because they have to be somewhere ! And as I use an address, there is no reason that at the same address, I can't find my data. And the code posted above proves that: I display the pointer value before DllCall, and after DllCall this value has changed in the $ver array ! That's the reason why I don't find my data - new space has been allocated and the pointers don't fit !

Here is a screen shot showing the code and the altered pointer:

http://www.4shared.com/photo/N63IowVZ/aa2.html

Edited by klausgunther
Posted (edited)

I don't get that!

Edit: Link to image removed.

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Posted

I can't believe it ! What is wrong with my installation ? My installed version is "Production Version 3.3.8.1 from January 29th, 2012. Should I go to the Beta version ? Are there eventually options I missed ? How do you happen to have the MsgBox output "Initial version" in the message display at the bottom ? I feel quite dumb, and, believe me, I studied the documentation and made litterally hundreds of tests ! Why is it working on your machines and not on my good old WP Pro SP3 ?

Posted (edited)

As you can see on my pic I run on this machine version 3.3.8.1 like you so it's almost sure isn't something wrong with AutoIt. I used ConsoleWrite function to display the results in console. Check out line 7 from code. This function is often used for debug. ;)

Edited by Andreik
Posted

Thank you for the ConsoleWrite hint. I integrated it - ist usefull.

But inspite of all my trials, I just cant get the same result as you, with my own software ! It insists in changing the pointer value, and the resulting string is not the one I copy, but just the initial content. There must be an installation dependent problem, but what ? I use Scite Version 3.2.0 Jun 9 2012 00:35:28, but even double-clicking the *.au3 file produces the same result. There must be a problem with the AutoIt iinstallation.I even tried to uninstall and reinstall the software; No error message during installation but no change in behaviour.

Posted (edited)

I doubt it's an AutoIt problem, though since I don't know what the cause is I can't be sure. But to see if it's your dll, would you like to try with my version which was compiled in D7 which was the nearest I have to your version?

I am also using WXP sp3.

Edit: linked removed since it has served its purpose.

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Posted

I tried your Delphi 7 DLL, and it worked ! Now it's clear: I have to look at my local DLL generation. It's strange because it works fine with Delphi 6 main programs and with programs written in Panoramic, just not with AutoIt. But now, I have a better hint for the origin of the problem.

Thank you very much for your help - I'll come back as soon as I know more about that.

Posted (edited)

I made one with VC++

Local $tString = DllStructCreate("char Version[25]")

ConsoleWrite(DllStructGetPtr($tString) & @CRLF)

Local $aVersion = DllCall("Test.dll","int:cdecl","KGFdllVersion","ptr",DllStructGetPtr($tString))

MsgBox(0,"","Returned value: " & $aVersion[0] & @CRLF & _
            "Struct pointer: " & $aVersion[1] & @CRLF & _
            "String: " & DllStructGetData($tString,"Version"))

Test.dll

Edit: too late, seems you get it

Edited by Andreik
Posted

Yes, Andreik, I'm tracing it down.

I noticed first of all, that I mixed up my DLL versions. I'm using Delphi 6 Personal Edition, and I'm trying to migrate my DLLs to Windows 64 bit environment. Unfortunately, this is impossible with Delphi 6 (and Delphi 7 too, btw). So, I looked for a freeware tool capable to take more or less my Delphi code and cross-compile Windows 64 bit compatible DLLs.

I found it with FreePaskal and Lazarus IDE. So, I'm constantly swapping between Delphi and FPC versions, and there is the problem: it works totally fine with mey Delphi DLL, as it does on your machines. But it's the Lazarus-FreePaskal version who runs into trouble. This version still works fine when called from a Delphi 6 mainline program, or from a Panoramic Basic program. Called from AutoIt, however, it produces the problem you know. Here is a ZIP file with test.au3 and the DLL posing problem: FPC_KGF.dll in 32 bit Windows version. Yes, I changed the name of the FPC version and now, there is no more confusion in selecting the DLL. The FPC_KGF.dll works fine form a Delphi 6 mainlice program, from a Panoramic Basic program, and even on Windows 7 64 bits with AutoIt in 64 bit mode (when I recompile it with the 64 bit cross-compiler) ! But not on Windows XP in 32 bit mode ! That's what I desperately try to obtain, and I'm really sorry for confusing the helpfull forum members by my own version confusion. But now, it's all clear, and the problem is obvious. Take the following Zip:

http://www.4shared.com/zip/4dFCSfnR/FPC_KGF.html

start test.au3 on a Windows 32 bit and see the problem. It's frustrating ! I managed the 64 bit conversion, testable by AutoIt, but no way to test the 32 bit version on a 32 bit system !

Posted (edited)

This is the way how it's work with new dll:

$dll = DllOpen("FPC_KGF.dll")

$ver = DllCall($dll, "int", "KGFdllVersion", "str*", "")

MsgBox(0,"","Return value: " & $ver[0] & @CRLF & _
            "MyString: " & $ver[1])

DllClose($dll)

Posted Image

Or something like this:

$dll = DllOpen("FPC_KGF.dll")

$ver = DllCall($dll, "int", "KGFdllVersion", "ptr*","12345678901234567890123456")

MsgBox(0,"","Return value: " & $ver[0] & @CRLF & _
            "String: " & $ver[1])

MsgBox(0,"Result",DllStructGetData(DllStructCreate("char v[25]",$ver[1]),"v"))

DllClose($dll)
Edited by Andreik
Posted

Oh yes, I know this one !

But I have to get it to work with the pointer trick, like in the posted code:

ConsoleWrite("Initial pointer: " & DllStructGetPtr($stString))

$ver = DllCall($dll, "int", "KGFdllVersion", "ptr*", DllStructGetPtr($stString))

MsgBox(0,"","Return value: " & $ver[0] & @CRLF _

& "Structure pointer: " & $ver[1] & @CRLF _

& "Data from structure: " & DllStructGetData($stString,"v") & @CRLF _

& "Data from structure: " & DllStructGetData($stString,1))

Just as it does with the DLL in Delphi 7 and Delphi 6, I have to see the string variable whose data bytes are modified ! I can't see why it works with Delphi 6 and 7 DLL's, but not with FPC DLLs !

Your example is working in that the result is returned in a newly generated variable. But that is not what I want to do. I want to modify the data bytes of an existing variable using pointers internally. Why do I complicate the problem ? That's because this small function is just a small test case for far more complex functions, some of which returning several strings, others a mix of string and several integer values, etc. Some even return complete contents of internal TStringList and other objects. That's why the memory pointer mechanic is so important. It' really not just for pushing you arround.

Posted

Why do I complicate the problem ?

I don't think so. ^_^

Maybe it's because I don't know very well Delphi to go deep into your code to see where is the problem. I'll take some delphi references to see what happens inside there.

Posted (edited)

I'm a bit slow, maybe that's the reason I don't see any problem here. If you use:

"str*", 0
...then AutoIt will inerpret pointer as null-terminated string, read it and return the string value found there.

If, on the other hand, you write:

"ptr*", 0
...you will get some pointer (to a string you say). What you do with that pointer is up to you. You can interpret it as string and read it from there (Andreik's second example) or if you think it's a smart idea you could write new string there. In both of those cases you use DllStruct functions. Former would be DllStructGetData() and latter DllStructSetData().

Why two pages of the thread are needed for this is mystery to me.

Edited by trancexx

♡♡♡

.

eMyvnE

Posted

You are right: just for this function, I don't really need it. But please keep in mind that, while this is a real function from my huge DLL (over 10,000 lines of Delphi 6 code), I took it as an example precisely to check the "write to address" feature. Other functions of my DLLs use this feature intensely, and not only to override a whole string, as in that example. Sometimes, only some specific portions are overwritten, sometimes the pointer points to other thongs than strings (floating point arrays, Windows API parameter blocks etc). I'm actually transposing all my DLLs from Delphi 6 to Lazarus/Free-Paskal, because that's the only free mean I have to cross-compile 64 bitt DLLs on my good old 32 bit XP Pro. So, I plan to use AutoIt to quick_check if a newly converted function in the Paskal version is behaving as before. But this implies that I have to test the function in the same conditions. That's why I insist so much on memory acces by pointers, and thanks to several of you really patient guys showed me the way - thanks again.

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...