Andreik Posted December 28, 2012 Posted December 28, 2012 (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 December 28, 2012 by Andreik
martin Posted December 28, 2012 Posted December 28, 2012 ...@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.
klausgunther Posted December 28, 2012 Author Posted December 28, 2012 (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 December 28, 2012 by klausgunther
martin Posted December 28, 2012 Posted December 28, 2012 (edited) I don't get that! Edit: Link to image removed. Edited December 29, 2012 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.
klausgunther Posted December 28, 2012 Author Posted December 28, 2012 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 ?
Andreik Posted December 28, 2012 Posted December 28, 2012 (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 December 28, 2012 by Andreik
klausgunther Posted December 28, 2012 Author Posted December 28, 2012 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.
Andreik Posted December 28, 2012 Posted December 28, 2012 SciTE cannot be the problem here. Have you tried running beta version? Have you an x64 OS version?
klausgunther Posted December 28, 2012 Author Posted December 28, 2012 No, I didn't try the beta version. I'm with production version 3.3.8.1. And my system is good old 32 bit Windows XP Pro SP3 - nothing fancy. It's really quite frustrating...
martin Posted December 28, 2012 Posted December 28, 2012 (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 December 29, 2012 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.
klausgunther Posted December 28, 2012 Author Posted December 28, 2012 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.
Andreik Posted December 28, 2012 Posted December 28, 2012 (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.dllEdit: too late, seems you get it Edited December 28, 2012 by Andreik
klausgunther Posted December 28, 2012 Author Posted December 28, 2012 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.htmlstart 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 !
Andreik Posted December 28, 2012 Posted December 28, 2012 (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)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 December 28, 2012 by Andreik
klausgunther Posted December 28, 2012 Author Posted December 28, 2012 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.
Andreik Posted December 28, 2012 Posted December 28, 2012 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.
klausgunther Posted December 29, 2012 Author Posted December 29, 2012 Thank you for having a look. But please remember: the problem lies in the Lazarus-FreePaskal version of the DLL (FPC_DLL.dll). I give the link again to the ZIP file containing all sources:http://www.4shared.com/zip/4dFCSfnR/FPC_KGF.htmlThe sources make up a Lazarus project, and the langage if FreePaskal, not Delphi.
trancexx Posted December 29, 2012 Posted December 29, 2012 (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 December 29, 2012 by trancexx ♡♡♡ . eMyvnE
klausgunther Posted December 29, 2012 Author Posted December 29, 2012 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.
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