Jump to content

AIOStruct.au3 - DllStruct wrapper for AutoItObject UDF


doudou
 Share

Recommended Posts

I don't know if somebody else already had got this idea (I couldn't find anything similar in the forum). Anyway, I needed this functionality for another project and thought it would not hurt to share it.

This neat little UDF wraps DllStructs into an AutoItObject. This not only increases comfort and simplifies syntax when handling structs but also allows use structs as property or function parameter in objects.

Use it like this (more elaborate examples are attached):

#include <AIOStruct.au3>
_AutoItObject_Startup()
Dim $tagStruct = "int myInt; char myString[128]"
Dim $objStruct = AIOStruct_New($tagStruct)
$objStruct.myInt = 0
$objStruct.myString = "Blah"

Please note: wrapping structs into objects costs performance and memory, thus if some of it is important you'd be better off with the plain DllStruct.

Version 1.0.1

  • AIOStruct: added StructSize property and ReadStruct() method
  • AIOStruct_Usage: added example for ReadStruct()
Version 1.1.0

  • AIOStructMgd: new wrapper with managed memory pointer
  • AIOStructMgd_Usage: new example for AIOStructMgd
Version 1.1.1

  • AIOStructMgd: GetPtr() is now possible for struct elements
  • AIOStructMgd_Usage: example for GetPtr($element) added
Version 1.1.2

  • AIOStruct: some missing type checks added
  • AIOStructMgd: implemented dynamic memory allocation

AIOStruct_Usage.au3

AIOStructMgd_Usage.au3

AIOStruct.au3

AIOStructMgd.au3

Edited by doudou

UDFS & Apps:

Spoiler

DDEML.au3 - DDE Client + Server
Localization.au3 - localize your scripts
TLI.au3 - type information on COM objects (TLBINF emulation)
TLBAutoEnum.au3 - auto-import of COM constants (enums)
AU3Automation - export AU3 scripts via COM interfaces
TypeLibInspector - OleView was yesterday

Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE 

Link to comment
Share on other sites

How can I get get the pointer to the structure? (Besides copying the whole structure back to a regular DllStruct)

There is no such pointer: the struct itself isn't (and cannot be) saved anywhere in the object, only data. This is due to limitations of AutotIt and - inherited wise - of AutoItObject, those limitations have driven me to writing this UDF in first place.

UDFS & Apps:

Spoiler

DDEML.au3 - DDE Client + Server
Localization.au3 - localize your scripts
TLI.au3 - type information on COM objects (TLBINF emulation)
TLBAutoEnum.au3 - auto-import of COM constants (enums)
AU3Automation - export AU3 scripts via COM interfaces
TypeLibInspector - OleView was yesterday

Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE 

Link to comment
Share on other sites

The only problem is to save the DLLstruct somewhere... You'll have to use a global array I think.

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

You can do this when creating:

_AutoItObject_AddProperty($result, "__default__", $ELSCOPE_READONLY, Number(DllStructGetPtr($t)))

And get pointer (number) like this:

ConsoleWrite("---Address of structure (in form of number) = " & $objStruct() & @CRLF)

Right?

Yeah.. but no... but yeah... but no (greetings from Viki Pollard)

This is dangerous thing to do as we have to ensure that that pointer is valid throughout the entire live cycle of the object, which we cannot. Besides this procedure would either bloat the UDF (additional property setter for each struct element are required) or we will end up with copying back the members to the struct again (only this time to the saved pointer).

UDFS & Apps:

Spoiler

DDEML.au3 - DDE Client + Server
Localization.au3 - localize your scripts
TLI.au3 - type information on COM objects (TLBINF emulation)
TLBAutoEnum.au3 - auto-import of COM constants (enums)
AU3Automation - export AU3 scripts via COM interfaces
TypeLibInspector - OleView was yesterday

Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE 

Link to comment
Share on other sites

The only problem is to save the DLLstruct somewhere... You'll have to use a global array I think.

I don't see this as a problem. Copying data at once in $obj.GetStruct() or reading DllStruct pointer and copying each member in an accessor - is there a significant difference? Only that the latter is much more complicated to maintain (access violations rising).

UDFS & Apps:

Spoiler

DDEML.au3 - DDE Client + Server
Localization.au3 - localize your scripts
TLI.au3 - type information on COM objects (TLBINF emulation)
TLBAutoEnum.au3 - auto-import of COM constants (enums)
AU3Automation - export AU3 scripts via COM interfaces
TypeLibInspector - OleView was yesterday

Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE 

Link to comment
Share on other sites

I don't see this as a problem. Copying data at once in $obj.GetStruct() or reading DllStruct pointer and copying each member in an accessor - is there a significant difference? Only that the latter is much more complicated to maintain (access violations rising).

DLLStructs are not supported in AutoItObject. You can not return a struct from a function. If you return a pointer, the struct it is pointing to has to be saved at some place, too. A global variable is the only solution to do that in an Object-method for access from outside the function. Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

DLLStructs are not supported in AutoItObject. You can not return a struct from a function.

Exactly that was the motivation behind AIOStruct. I had a custom AIO that needed access to a struct internally, after fiddling with pointers and allocs for a while I decided to write AIOStruct, so I can do this:

Dim $objStruct = AIOStruct_New($tagStruct, $pointer)
Dim $obj = _AutoItObject_Create()
_AutoItObject_AddProperty($obj, "_Struct", $ELSCOPE_PRIVATE, $objStruct)

If you return a pointer, the struct it is pointing to has to be saved at some place, too. A global variable is the only solution to do that in an Object-method for access from outside the function.

I don't get it, WHY we need a solution? And for what? AIOStruct isn't intended to be a replacement for DllStruct, the original pointer isn't needed to achieve its goals. Period. Edited by doudou

UDFS & Apps:

Spoiler

DDEML.au3 - DDE Client + Server
Localization.au3 - localize your scripts
TLI.au3 - type information on COM objects (TLBINF emulation)
TLBAutoEnum.au3 - auto-import of COM constants (enums)
AU3Automation - export AU3 scripts via COM interfaces
TypeLibInspector - OleView was yesterday

Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE 

Link to comment
Share on other sites

Alright. I misinterpreted your response, I thought you were thinking about a solution. Personally I don't see a reason to solve this, too.

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

I added 2 features missed in the 1st release (s. the top post).

UDFS & Apps:

Spoiler

DDEML.au3 - DDE Client + Server
Localization.au3 - localize your scripts
TLI.au3 - type information on COM objects (TLBINF emulation)
TLBAutoEnum.au3 - auto-import of COM constants (enums)
AU3Automation - export AU3 scripts via COM interfaces
TypeLibInspector - OleView was yesterday

Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE 

Link to comment
Share on other sites

There is a reason why I asked that question...

I've tried to do this too. But because of that problem, suddenly all the pros (except cleaner syntax) just ran away.

I'm sure there's a good reason for your question. But 1stly the idea behind the AIOStruct was not primarily to have cooler syntax but possibility using sturcts in object calls and properties without pointer mambo-jambo (s. my reply to ProgAndy) and 2ndly if you want to use AIOStruct like DLLStruct you still can do it - just some additional calls are needed (s. AIOStruct_Usage.au3).

And finally I think I gonna give in :( and create a second incarnation of AIOStruct which will make access to struct pointer easier (and will have some restrictions comparing to AIOStruct though).

UDFS & Apps:

Spoiler

DDEML.au3 - DDE Client + Server
Localization.au3 - localize your scripts
TLI.au3 - type information on COM objects (TLBINF emulation)
TLBAutoEnum.au3 - auto-import of COM constants (enums)
AU3Automation - export AU3 scripts via COM interfaces
TypeLibInspector - OleView was yesterday

Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE 

Link to comment
Share on other sites

There is a sort of a "missing link" that would make creation of this kind of objects sensible. It's __name__ property for the object. It would be set to the name of the object function the code is currently running in.

You will see what I mean after consultations with others.

This would be valid syntax in that case:

$oTimeStruct = _AutoItObject_DllStructCreate($tagSYSTEMTIME)
DllCall("kernel32.dll", "none", "GetSystemTime", "ptr", $oTimeStruct())
$iYear = $oTimeStruct.Year ; reading
ConsoleWrite($iYear & @CRLF) ; print
$oTimeStruct.Year = 2011 ; setting
$iYear = $oTimeStruct.Year ; reading again
ConsoleWrite($iYear & @CRLF) ; print

And method dealing with setting or reading (for every 'element') would be something like this:

Func _MethodMain($oSelf, $vParam1 = 0, $vParam2 = 0)
    Local $sMethod = $oSelf.__name__
    Local $tStructure = DllStructCreate($oSelf.__tag__, $oSelf())
    Switch @NumParams
        Case 1
            Return Number(DllStructGetData($tStructure, $sMethod))
        Case 2
            If $oSelf.__propcall__ Then
                Return Number(DllStructSetData($tStructure, $sMethod, $vParam1))
            Else
                Return Number(DllStructGetData($tStructure, $sMethod, $vParam1))
            EndIf
        Case 3
            Return Number(DllStructSetData($tStructure, $sMethod, $vParam2, $vParam1))
    EndSwitch
EndFunc

edit: That's over-numbered lol

Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

There is a sort of a "missing link" that would make creation of these kind of objects sensible. It's __name__ property for the object. It would be set to the name of the object function the code is currently running in.

You will see what I mean after consultations with others.

This would be valid syntax in that case:

$oTimeStruct = _AutoItObject_DllStructCreate($tagSYSTEMTIME)
DllCall("kernel32.dll", "none", "GetSystemTime", "ptr", $oTimeStruct())
$iYear = $oTimeStruct.Year ; reading
ConsoleWrite($iYear & @CRLF) ; print
$oTimeStruct.Year = 2011 ; setting
$iYear = $oTimeStruct.Year ; reading again
ConsoleWrite($iYear & @CRLF) ; print

Ah? Did I miss an AutoItObject release? Where did this _AutoItObject_DllStructCreate come from? Edited by doudou

UDFS & Apps:

Spoiler

DDEML.au3 - DDE Client + Server
Localization.au3 - localize your scripts
TLI.au3 - type information on COM objects (TLBINF emulation)
TLBAutoEnum.au3 - auto-import of COM constants (enums)
AU3Automation - export AU3 scripts via COM interfaces
TypeLibInspector - OleView was yesterday

Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE 

Link to comment
Share on other sites

By (popular?) demand I added a subclass of AIOStruct with managed memory and GetPtr() method (s. top post).

This is the closest thing to DllStruct I see possible for now. Maybe if the fog around trancexx' comments :( clears a bit we can talk about default properties.

UDFS & Apps:

Spoiler

DDEML.au3 - DDE Client + Server
Localization.au3 - localize your scripts
TLI.au3 - type information on COM objects (TLBINF emulation)
TLBAutoEnum.au3 - auto-import of COM constants (enums)
AU3Automation - export AU3 scripts via COM interfaces
TypeLibInspector - OleView was yesterday

Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE 

Link to comment
Share on other sites

There is a sort of a "missing link" that would make creation of this kind of objects sensible. It's __name__ property for the object. It would be set to the name of the object function the code is currently running in.

Slowly I begin to follow...

Well, this is imagined future of AutoItObject we are talking about, isn't it? Even if AIO supported that (what would be super), I actually would want to avoid property getters for struct elements though a single default getter for a __name__ would certainly reduce memory footprint.

UDFS & Apps:

Spoiler

DDEML.au3 - DDE Client + Server
Localization.au3 - localize your scripts
TLI.au3 - type information on COM objects (TLBINF emulation)
TLBAutoEnum.au3 - auto-import of COM constants (enums)
AU3Automation - export AU3 scripts via COM interfaces
TypeLibInspector - OleView was yesterday

Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE 

Link to comment
Share on other sites

Slowly I begin to follow...

Well, this is imagined future of AutoItObject we are talking about, isn't it? Even if AIO supported that (what would be super), I actually would want to avoid property getters for struct elements though a single default getter for a __name__ would certainly reduce memory footprint.

Actually, my part is over. To the others now...

♡♡♡

.

eMyvnE

Link to comment
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
 Share

  • Recently Browsing   0 members

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