Modify

Opened 5 years ago

Last modified 5 years ago

#2890 new Feature Request

DllStructGetString

Reported by: Mars (AutoIt.de) Owned by:
Milestone: Component: AutoIt
Version: Severity: None
Keywords: DllStructGetString Cc:

Description

Request: DllStructGetString: Struct -> String
Returns the string used to create the struct.
;---------------------------------------------

Currently, it is impossible to get the string that was used to create a DllStruct.

For example: Try to write a _DllStructToString($vStr) (and vice versa) function. (like Array2Str and Str2Array). Without DllStructGetString this should be very hard to manage.

Surely it is possible to pass the string otherways (workarounds are never the best way...), but that is not the point. AutoIt should "know" that string, because you can access the structcontent via "abc". So it should be easy to create a BuildIn function that can return it.

Global $vStr = DllStructCreate('int;double')
Global $sStr = DllStructGetString($vStr)
;~ $sStr = 'int;double'

mfg
Mars

Attachments (0)

Change History (10)

comment:1 Changed 5 years ago by TicketCleanup

  • Version 3.3.12.0 deleted

Automatic ticket cleanup.

comment:2 follow-up: Changed 5 years ago by Melba23

If you created the struct within the script, you either defined it or you used a pre-defined structure from within the StructureConstants include file. As a result you must already know the string used. Why therefore do you need a function to tell you?

M23

comment:3 in reply to: ↑ 2 Changed 5 years ago by anonymous

Replying to Melba23:

If you created the struct within the script, you either defined it or you used a pre-defined structure from within the StructureConstants include file. As a result you must already know the string used. Why therefore do you need a function to tell you?

M23

The argumentation is similar to - "why do I need UBound? I already defined my array and for every resize I could use a second variable to save its size". It is meant to reduce complexity of some scripts.

Another example: You want a function that can copy any struct (with its content).
Surely it is possible to write _DllStructCopy($vStr, $sStr) = $vCopy, but it is impossible to cut out the second parameter and if you do not know what kind of struct you have, you are lost.
A workaround would be including the definition inside the struct itself, but this would make no sense since "constants" must not be altered.

Mars

comment:4 Changed 5 years ago by Melba23

I do not accept the "similar to UBound" argument, Arrays are dynamic variables and can be expected to change size, or even be created with an unknown size by called functions, so having a way to return the actual size is quite reasonable. But structs are not dynamic, so in my opinion the argument fails.

And your second point leaves me perplexed - as I pointed out above, how can you not know what kind of struct you are trying to copy? Storing the creation string for later use does not seem overly onerous.

Do not get me wrong, I am not looking for an excuse to close the ticket, merely for a sensible reason as to why such a function would be required. Perhaps you could provide a more concrete case where you do not have an idea of the internal structure of a struct and you really need to know. Merely not having to use a second parameter defining the string (as you seem to suggest above) does not seem a good enough reason to me.

M23

comment:5 Changed 5 years ago by BrewManNH

You could always do something like this to recreate the struct.

For $i = 1 To 100
	$StructData = DllStructGetData($tSTRUCT1, $i)
	If @error Then ExitLoop
	ConsoleWrite("Value of element " & $i & " = " & $StructData & @TAB & " Type = " & VarGetType($StructData) & @CRLF)
Next

Unfortunately the argument using UBound is invalid, there are dozens of reasons why you don't know the full size of an array. FileListToArray gives you a list of files in a folder, you'd never know how many items were in that folder prior to reading them. _FileReadToArray, reads a file into an array, one line of text per element. Unless you knew exactly how many lines were in the file, you'd never know the count of the array.

comment:6 Changed 5 years ago by Mars

The problem is that there is not just one way of doing it. The UBound "argument" should only show this purpose. In the end we only need a Turing-complete language.
[ OT]

  1. Arrays are dynamic, but noone forbids me to add 1 to my counter variable.
  2. Every BuildIn or UDF-Func can return the Arraysize in the first element (_FileReadToArray can but FileReadToArray cannot... this was only changed to make my argument invalid ;) ).
  3. The example that shows me how to access a struct cannot get any keys "int a;int b" and it cannot represent half of the datatypes.

[ /OT]
For a good example you may look at http://autoit.de/index.php?page=Thread&threadID=45500
It is impossible to complete this function without a GetString function. I tried many ways to solve this problem, I read many threads in many forums. It seems there is no other (universal) way.

Mars

comment:7 Changed 5 years ago by jchd18

I partly agree with the proposal, for debugging purposes. FYI look at how I currently dump structures with the code linked below. It shows that reverse-engineering the internals of all basic structures is definitely possible (even if unduly painful).
I didn't take the pain to develop ugly code to detect align directives potentially used in structs and that is precisely why I softly agree.

https://dl.dropboxusercontent.com/u/26433628/Dump.au3

comment:8 Changed 5 years ago by anonymous

The dump function is a good example. It cannot reproduce the correct datatypes (see alias for int64/int32/ptr) and it cannot detect any labels like "int xPos;int yPos".

comment:9 follow-up: Changed 5 years ago by BrewManNH

Is there a way to return the initializer list for a struct in another language? Or to know what the labels are named once a struct has been created in another language? I've been googling this and haven't seen an answer to this, so I was curious how other languages do it.

comment:10 in reply to: ↑ 9 Changed 5 years ago by anonymous

Most languages use reflection.

I'd suggest an additional function: DllStructGetType, which returns a handle for a "DllStructType". Elements of that type can be created and used as follows:

; Changed signature.
DllStructCreate ($typeString : String, optional $pointer : Ptr) : DllStruct
DllStructCreate ($type : DllStructType, optional $pointer : Ptr) : DllStruct

; New.
DllStructGetType ($struct : DllStruct) : DllStructType

; New.
DllStructType ($typeString : String) : DllStructType
DllStructTypeGetString ($type : DllStructType) : String
DllStructTypeGetElement ($type : DllStructType, $index : Int32) : DllStructTypeElement
DllStructTypeGetElements ($type : DllStructType) : DllStructTypeElement []
DllStructTypeGetElementCount ($type : DllStructType) : Int32
DllStructTypeGetSize ($type : DllStructType) : Int32

A DllStructTypeElement should be a map like {index: 2, name: "third", type: "uint32[2]", originalType: "dword[2]", offset: 8, size: 8}. The type is always the same, even if the original type is ulong[2] or dword[2]. That way the caller of the function won't have to handle all cases, which might increase in the future.
An array of DllStructTypeElements isn't enough, because that doesn't contain the size of the whole struct.
It might be useful to be able to "concatenate" two struct types without worrying about semicolons.

Guidelines for posting comments:

  • You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
  • In-depth discussions should take place on the forum.

For more information see the full version of the ticket guidelines here.

Add Comment

Modify Ticket

Action
as new The ticket will remain with no owner.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.