manni Posted December 8, 2008 Share Posted December 8, 2008 Hi all, I'm having problems with DllStructCreate: When running the following script, it enters an infinite loop, because DllStructCreate returns always the same memory address (obtained with DllStructGetPtr() ) #include <Array.au3> Global $Cmds[1] ; array of <pointers to $tagCMD> Global $tagCMD = "char Name[128]; ubyte CmdLen; byte Cmd[100]" For $i = 1 To 10 $new = DllStructCreate($tagCMD) $ptr = DllStructGetPtr($new) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ptr = ' & $ptr & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console Local $index = _ArraySearch ( $Cmds, $ptr ) While $index <> -1 ; $ptr is already in array, so create a new struct ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $index = ' & $index & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console $new = DllStructCreate($tagCMD) $ptr = DllStructGetPtr($new) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ptr = ' & $ptr & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console $index = _ArraySearch ( $Cmds, $ptr ) WEnd _ArrayAdd ( $Cmds, $ptr ) Next _ArrayDisplay ( $Cmds ) Anyone got an idea, what's wrong here? Thanks in advance Link to comment Share on other sites More sharing options...
martin Posted December 8, 2008 Share Posted December 8, 2008 Hi all, I'm having problems with DllStructCreate: When running the following script, it enters an infinite loop, because DllStructCreate returns always the same memory address (obtained with DllStructGetPtr() ) #include <Array.au3> Global $Cmds[1] ; array of <pointers to $tagCMD> Global $tagCMD = "char Name[128]; ubyte CmdLen; byte Cmd[100]" For $i = 1 To 10 $new = DllStructCreate($tagCMD) $ptr = DllStructGetPtr($new) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ptr = ' & $ptr & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console Local $index = _ArraySearch ( $Cmds, $ptr ) While $index <> -1 ; $ptr is already in array, so create a new struct ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $index = ' & $index & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console $new = DllStructCreate($tagCMD) $ptr = DllStructGetPtr($new) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ptr = ' & $ptr & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console $index = _ArraySearch ( $Cmds, $ptr ) WEnd _ArrayAdd ( $Cmds, $ptr ) Next _ArrayDisplay ( $Cmds ) Anyone got an idea, what's wrong here? Thanks in advance Can you explain what you want to do? I don't undrstand why you keep recreating the same struct for example. This would make some sense to me. #include <Array.au3> Global $Cmds[10]; array of <pointers to $tagCMD> Global $New[10] Global $tagCMD = "char Name[128]; ubyte CmdLen; byte Cmd[100]" For $i = 0 To 9 $new[$i] = DllStructCreate($tagCMD) _ArrayAdd($cmds,DllstructGetPtr($new[$i]) Next _ArrayDisplay ( $Cmds ) 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. Link to comment Share on other sites More sharing options...
manni Posted December 8, 2008 Author Share Posted December 8, 2008 (edited) martin, first of all thanks for the quick response! Basically i want exactly what you proposed, namely an array of pointers to my structure. What I don't unterstand, havever, is that consecutive calls to DllStructCreate() always rerturn the same memory address. In my understanding, there should be a new memory allocation with every call to DllStructCreate(), because I do not pass a pointer (as 2nd arg) to the function. Am i wrong with that assumption? thanks Edited December 8, 2008 by manni Link to comment Share on other sites More sharing options...
monoceres Posted December 8, 2008 Share Posted December 8, 2008 The memory address is the same because the struct is destroyed along with the handle for the struct. AutoIt doesn't care if you have a pointer to the struct stored somewhere. So what you have to do is save the handle to the struct somewhere, where it doesn't get destroyed until you want to. Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
manni Posted December 8, 2008 Author Share Posted December 8, 2008 Ahhhhh! Now I got it. That works: #include <Array.au3> Global $Cmds[1]; array of <pointers to $tagCMD> Global $tagCMD = "char Name[128]; ubyte CmdLen; byte Cmd[100]" For $i = 0 To 9 _ArrayAdd($cmds,DllStructCreate($tagCMD) ) Next For $i = 0 To 9 $struct = $Cmds[$i] $ptr = DllStructGetPtr ( $struct ) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ptr = ' & $ptr & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console Next Thanks for your replies! Link to comment Share on other sites More sharing options...
martin Posted December 8, 2008 Share Posted December 8, 2008 (edited) The memory address is the same because the struct is destroyed along with the handle for the struct. AutoIt doesn't care if you have a pointer to the struct stored somewhere. So what you have to do is save the handle to the struct somewhere, where it doesn't get destroyed until you want to.Well I think manni has a point. If you create a label for example GUICreate("nothing") $lab = GuiCtrlCreateLabel("one",30,40,100,22) consolewrite($lab & @CR) $lab = GuiCtrlCreateLabel("two",30,40,100,22) consolewrite($lab & @CR) then the second label doesn't replace the first. Nothing explicitly destroys the struct so it would be reasonable to assume that it still exists. IMO it could be argued either way, but as it is you just have to learn that dllstructs are different I suppose. BIG EDIT: That is all wrong! The struct isn't destroyed and the pointer isn't the same $a = dllstructcreate("int") ConsoleWrite(DllStructGetPtr($a) & @CRLF) $a = dllstructcreate("int") ConsoleWrite(DllStructGetPtr($a) & @CRLF) I'll look at manni's code again. Edited December 8, 2008 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. Link to comment Share on other sites More sharing options...
martin Posted December 8, 2008 Share Posted December 8, 2008 The problem was not that dllstructs were getting overwritten, but that the script was wrong. Here is what I think it should have been #include <Array.au3> Global $Cmds[1] = [0]; array of <pointers to $tagCMD> Global $tagCMD = "char Name[128]; ubyte CmdLen; byte Cmd[100]" Global $new,$ptr For $i = 1 To 10 $new = DllStructCreate($tagCMD) $ptr = DllStructGetPtr($new) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ptr = ' & $ptr & @crlf & '>Error code: ' & @error & @crlf);### Debug Console _ArrayAdd ( $Cmds, $ptr ) Local $index = _ArraySearch ( $Cmds, $ptr ) ConsoleWrite("line 12 $index =" & $index & @CRLF) While $index = -1 ; $ptr is already in array, so create a new struct ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $index = ' & $index & @crlf & '>Error code: ' & @error & @crlf);### Debug Console $new = DllStructCreate($tagCMD) $ptr = DllStructGetPtr($new) _ArrayAdd ( $Cmds, $ptr ) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ptr = ' & $ptr & @crlf & '>Error code: ' & @error & @crlf);### Debug Console $index = _ArraySearch ( $Cmds, $ptr ) WEnd Next _ArrayDisplay ( $Cmds ) 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. Link to comment Share on other sites More sharing options...
manni Posted December 8, 2008 Author Share Posted December 8, 2008 The problem was not that dllstructs were getting overwritten, but that the script was wrong. Here is what I think it should have been #include <Array.au3> Global $Cmds[1] = [0]; array of <pointers to $tagCMD> Global $tagCMD = "char Name[128]; ubyte CmdLen; byte Cmd[100]" Global $new,$ptr For $i = 1 To 10 $new = DllStructCreate($tagCMD) $ptr = DllStructGetPtr($new) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ptr = ' & $ptr & @crlf & '>Error code: ' & @error & @crlf);### Debug Console _ArrayAdd ( $Cmds, $ptr ) Local $index = _ArraySearch ( $Cmds, $ptr ) ConsoleWrite("line 12 $index =" & $index & @CRLF) While $index = -1 ; $ptr is already in array, so create a new struct ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $index = ' & $index & @crlf & '>Error code: ' & @error & @crlf);### Debug Console $new = DllStructCreate($tagCMD) $ptr = DllStructGetPtr($new) _ArrayAdd ( $Cmds, $ptr ) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ptr = ' & $ptr & @crlf & '>Error code: ' & @error & @crlf);### Debug Console $index = _ArraySearch ( $Cmds, $ptr ) WEnd Next _ArrayDisplay ( $Cmds ) martin, when I run your proposed script and look at the output from _ArrayDisplay(), I see that, the odd entries Array[1], Array[3], Array[5] ... are all the same and the even entries are all the same, i.e they point to the same memory location. Any ideas about that? thanks Link to comment Share on other sites More sharing options...
monoceres Posted December 8, 2008 Share Posted December 8, 2008 BIG EDIT: That is all wrong! The struct isn't destroyed and the pointer isn't the same $a = dllstructcreate("int") ConsoleWrite(DllStructGetPtr($a) & @CRLF) $a = dllstructcreate("int") ConsoleWrite(DllStructGetPtr($a) & @CRLF) I'll look at manni's code again. I cannot test since I'm at a public pc, but I can say that I'm pretty sure the first struct is destroyed. The reason for the memory address change can be anything. Maybe AutoIt allocates new memory between the calls and more likely because when you call DllStructCreate() $a still exists. it doesn't get overwrited until the function returns. Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
martin Posted December 8, 2008 Share Posted December 8, 2008 I cannot test since I'm at a public pc, but I can say that I'm pretty sure the first struct is destroyed. The reason for the memory address change can be anything. Maybe AutoIt allocates new memory between the calls and more likely because when you call DllStructCreate() $a still exists. it doesn't get overwrited until the function returns.Ok, I believe that I haven't understood this yet but I don't think your explanation is correct either. Try this for example For $c = 1 To 16 $a = DllStructCreate("int") ConsoleWrite(DllStructGetPtr($a) & @CRLF) While 1 $a = DllStructCreate("int") ConsoleWrite(DllStructGetPtr($a) & @CRLF) ExitLoop WEnd Next This produced 0x01431FF0 0x003DDD18<-------repeated block start 0x01431F58 0x003DDE28 0x014312F0 0x01431FE0 0x003DDD08 0x003DBDC8 0x003DDD18<-------repeated block start 0x01431F58 0x003DDE28 0x014312F0 0x01431FE0 0x003DDD08 0x003DBDC8 0x003DDD18<-------repeated block start 0x01431F58 0x003DDE28 0x014312F0 0x01431FE0 0x003DDD08 0x003DBDC8 0x003DDD18<-------repeated block start 0x01431F58 0x003DDE28 0x014312F0 0x01431FE0 0x003DDD08 0x003DBDC8 0x003DDD18<-------repeated block start 0x01431F58 0x003DDE28 I don't understand that either 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. Link to comment Share on other sites More sharing options...
monoceres Posted December 8, 2008 Share Posted December 8, 2008 I really don't know what you're going with these numbers martin. They're kinda irrelevant since it's up to windows and autoit to give us pointers that points to valid blocks of memory we really shouldn't care if a specific number returns after a few allocations and deallocations. Made a small example also. $a=DllStructCreate("char[8];") DllStructSetData($a,1,"Andreas") $strptr=DllStructGetPtr($a) ConsoleWrite("Pointer to string is: "&$strptr&@CRLF); Output the pointer $a=DllStructCreate("int;"); The struct is created. However since the first $a is not destroyed until DllStructCreate() is done it's a new pointer DllStructSetData($a,1,1234); Set some random data $intptr=DllStructGetPtr($a) ConsoleWrite("Pointer to int is: "&$intptr&@CRLF); Outputs second data. This pointer could be anything and we really shouldn't care how it's connected to the first pointer ; even though they have different pointers, $strptr doesn't point to any valid data anymore (could even crash) ; This is because AutoIt has returned control of this block of memory to windows. $b=DllStructCreate("char[8];",$strptr) ConsoleWrite(DllStructGetData($b,1)&@CRLF) I'm not really sure what you mean though.. Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
martin Posted December 8, 2008 Share Posted December 8, 2008 I really don't know what you're going with these numbers martin. They're kinda irrelevant since it's up to windows and autoit to give us pointers that points to valid blocks of memory we really shouldn't care if a specific number returns after a few allocations and deallocations. Made a small example also. $a=DllStructCreate("char[8];") DllStructSetData($a,1,"Andreas") $strptr=DllStructGetPtr($a) ConsoleWrite("Pointer to string is: "&$strptr&@CRLF); Output the pointer $a=DllStructCreate("int;"); The struct is created. However since the first $a is not destroyed until DllStructCreate() is done it's a new pointer DllStructSetData($a,1,1234); Set some random data $intptr=DllStructGetPtr($a) ConsoleWrite("Pointer to int is: "&$intptr&@CRLF); Outputs second data. This pointer could be anything and we really shouldn't care how it's connected to the first pointer ; even though they have different pointers, $strptr doesn't point to any valid data anymore (could even crash) ; This is because AutoIt has returned control of this block of memory to windows. $b=DllStructCreate("char[8];",$strptr) ConsoleWrite(DllStructGetData($b,1)&@CRLF) I'm not really sure what you mean though.. I think the problem is that I've been confused [even more than I normally am ] I had forgotten that the way to destroy a dll struct is to assign the struct variable to 0 like this $astruct = DllSTructCreate("int") $astruct = 0;delete the struct or assigning the struct variable to any value destroys the old struct. Which is what you were trying to tell me. But I was trying to equate this, as I said in an earlier post, to the case where you create a label for eaxample. Assigning the variable to a new label doesn'y destroy the old label. However, a struct is not an object like a window and I was being daft . Sorry to waste your time with my confusion, and thanks for your time. When I grow up I hope to learn how to write programs. 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. Link to comment Share on other sites More sharing options...
monoceres Posted December 8, 2008 Share Posted December 8, 2008 I think the problem is that I've been confused [even more than I normally am ] I had forgotten that the way to destroy a dll struct is to assign the struct variable to 0 like this $astruct = DllSTructCreate("int") $astruct = 0;delete the struct or assigning the struct variable to any value destroys the old struct. Which is what you were trying to tell me. But I was trying to equate this, as I said in an earlier post, to the case where you create a label for eaxample. Assigning the variable to a new label doesn'y destroy the old label. However, a struct is not an object like a window and I was being daft . Sorry to waste your time with my confusion, and thanks for your time. When I grow up I hope to learn how to write programs. Don't mention it. It's great to be able to give back some of the help I have received from you Broken link? PM me and I'll send you the file! 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