Jump to content

Latest Beta


Jon
 Share

Recommended Posts

- Added: "struct" as DllCall and InterfaceDispatch data type.

"struct" is an alternative to its pointer?

$tData = DllStructCreate('int;int;ptr;wchar[128]')
DllCall('MyLib.dll', 'none', 'MyFunc', 'struct', $tData)

equivalent to

$tData = DllStructCreate('int;int;ptr;wchar[128]')
DllCall('MyLib.dll', 'none', 'MyFunc', 'ptr', DllStructGetPtr($tData))

or something else?

Link to comment
Share on other sites

struct is to add a structure directly on the parameter stack (inline) instead of a pointer. That is mainly done for structures with a maximum length of 8 bytes (e.g. POINT)

; EXAMPLE WORKS ONLY WITH 32BIT (x86) !
$c = DllCallbackRegister("_test", "int", "int;int")
 
$t = DllStructCreate("int;int")
DllStructSetData($t, 1, 0xDEAD)
DllStructSetData($t, 2, 0xBEEF)
DllCallAddress("int", DllCallbackGetPtr($c), "struct", $t)
 
Func _test($a, $b)
    ConsoleWrite(Hex($a) & " " & Hex($b) & @LF)
EndFunc

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

"struct" is an alternative to its pointer?

$tData = DllStructCreate('int;int;ptr;wchar[128]')
DllCall('MyLib.dll', 'none', 'MyFunc', 'struct', $tData)

equivalent to

$tData = DllStructCreate('int;int;ptr;wchar[128]')
DllCall('MyLib.dll', 'none', 'MyFunc', 'ptr', DllStructGetPtr($tData))

or something else?

trancexx tells me there is an equivalent way to this:

$tData = DllStructCreate('int;int;ptr;wchar[128]')
DllCall('MyLib.dll', 'none', 'MyFunc', 'ptr', DllStructGetPtr($tData))

It's probably this but I'm not sure, she will have to confirm:

$tData = DllStructCreate('int;int;ptr;wchar[128]')
DllCall('MyLib.dll', 'none', 'MyFunc', 'struct*', $tData)
Link to comment
Share on other sites

Let's see what struct type is, why it's added and how to use it.

struct is type identifier for parameters passed to DllCall() function and objects created with ObjectCreateInterface(). It tells AutoIt that parameter is to be interpreted as structure (composite type).

Essentially x64 systems (100 years ago) brought the need for this kind of identifier. More specifically the need for non-compiled scripts to be equally runnable both with/thru 64bit and 32bit version of the interpreter. This is one of three main rules for every good AutoIt script.

To show proper usage I'll use two examples. One is for struct* and other for struct.

struct* is, as said already used when you want to pass structure pointer. Previously you would use ptr type and function DllStructGetPtr($tSTRUCT). Not to create confusion of some sort you can still use that method, only it's recommended that you do something like this:

_Example1(64 + 262144, "Caption", "Some text to display.")
 
Func _Example1($iFlag, $sCaption, $sText)
    ; Some sub-structures required by the main structure below. Don't let this catch your eye.
    Local $tTEXT = DllStructCreate("wchar[" & StringLen($sText) + 1 & "]")
    DllStructSetData($tTEXT, 1, $sText)
    Local $tCAPTION = DllStructCreate("wchar[" & StringLen($sCaption) + 1 & "]")
    DllStructSetData($tCAPTION, 1, $sCaption)
    ; Create the main structure
    Local $tMSGBOXPARAMS = DllStructCreate("uint cbSize;" & _
            "hwnd hwndOwner;" & _
            "handle hInstance;" & _
            "ptr lpszText;" & _
            "ptr lpszCaption;" & _
            "dword dwStyle;" & _
            "ptr lpszIcon;" & _
            "dword_ptr dwContextHelpId;" & _
            "ptr lpfnMsgBoxCallback;" & _
            "dword dwLanguageId;")
    ; Fill it
    DllStructSetData($tMSGBOXPARAMS, "cbSize", DllStructGetSize($tMSGBOXPARAMS))
    DllStructSetData($tMSGBOXPARAMS, "lpszText", DllStructGetPtr($tTEXT))
    DllStructSetData($tMSGBOXPARAMS, "lpszCaption", DllStructGetPtr($tCAPTION))
    DllStructSetData($tMSGBOXPARAMS, "dwStyle", $iFlag)
    ; Call passing struct for "struct*" parameter type
    Local $aCall = DllCall("user32.dll", "int", "MessageBoxIndirectW", "struct*", $tMSGBOXPARAMS)
    If @error Then Return SetError(1, 0, -1)
    Return $aCall[0]
EndFunc

Another example is using struct type. This is where the whole magic is seen. Without struct type you are forced to use different workarounds not to cause stack corruption when your code is run with interpreter of wrong bitness.

Now you can elegantly push a blody structure as parameter:

ConsoleWrite(WinGetTitle(_Example2(10, 10)) & @CRLF)
 
Func _Example2($iX, $iY)
    ; Create structure
    Local $tPOINT = DllStructCreate("long x; long y")
    DllStructSetData($tPOINT, "x", $iX)
    DllStructSetData($tPOINT, "y", $iY)
    ; DllCall passing struct for "struct" param type
    Local $aCall = DllCall("user32.dll", "hwnd", "WindowFromPoint", "struct", $tPOINT)
    If @error Then Return SetError(1)
    Return $aCall[0]
EndFunc

Anyway, this is how different scenarios are handled:

Parameter description:                 Parameter type:                Action:
 
  - "struct"                               - dllstruct                    - accept and process sruct
  - "struct"                               - non-dllstruct                - error is raised
  - "struct*"                             - dllstruct                     - pointer to dllstruct is read internally
  - "struct*"                             - non-dllstruct                 - parameter is taken to be dllstruct pointer

As I said, the same thing applies to objects created with ObjCreateInterface, called InterfaceDispatch objects. Their description string can include struct and struct* type identifiers.

Edited by trancexx
Oh look, I can put reason for edit here.
Link to comment
Share on other sites

- "struct*"                          - dllstruct                     - pointer to dllstruct is read internally  
- "struct*"                          - non-dllstruct                 - parameter is taken to be dllstruct pointer
I like this. Now functions will be 2 lines shorter since you can omit the code to switch between DLLStruct and Pointer :graduated: 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

Func _Example2($iX, $iY)
    ; Create structure
    Local $tPOINT = DllStructCreate("long x; long y")
    DllStructSetData($tPOINT, "x", $iX)
    DllStructSetData($tPOINT, "y", $iY)
    ; DllCall passing struct for "struct" param type
    Local $aCall = DllCall("user32.dll", "hwnd", "WindowFromPoint", "struct", $tPOINT)
    If @error Then Return SetError(1)
    Return $aCall[0]
EndFunc

In this case, $aCall[1] contains the structure? If yes then $tPOINT and $aCall[1] use the same memory area?
Link to comment
Share on other sites

Hi guys and gals,

I'm sorry if my post is not in the right section of the forum, but I thought this would be the place for it since it concerns the latest Beta and I think only a developer can help pinning down the problem and fixing it.

So here is what is bugging me...

Up until recently I was using AutoIt version 3.3.6.1 and a couple of days ago I updated to 3.3.7.20.

I know it is quite a big leap in versions... :D

Once I updated, I started noticing huge delays in some of my scripts. I did some tests and the results were disturbing.

Here is a small script to reproduce the problem:

~

If I run this script with version 3.3.7.20, I get the following results from the timer:

[0]|0

[1]|541.476487013891-Before

[2]|686.634863950111-After

[3]|687.302898666596-Before

[4]|829.92120388384-After

[5]|830.553112609451-Before

[6]|967.714616516684-After

[7]|968.337049572558-Before

[8]|1108.72620348409-After

[9]|1109.4238496685-Before

[10]|1249.94862410314-After

[11]|1250.66877500318-Before

[12]|1388.78199148966-After

[13]|1389.43403601347-Before

[14]|1532.7032012958-After

[15]|1533.6140500493-Before

[16]|1678.39754580154-After

[17]|1679.143162564-Before

[18]|1825.38058139156-After

[19]|1825.98998540155-Before

[20]|1969.31482024358-After

[21]|1969.89402055628-Before

[22]|2111.68675804766-After

[23]|2112.36426843388-Before

[24]|2257.89693432473-After

[25]|2258.91319990406-Before

[26]|2400.24814410125-After

[27]|2400.87472276263-Before

[28]|2542.77524599727-After

[29]|2543.57120225521-Before

[30]|2683.40484502838-After

[31]|2683.7678816252

If I run this script with version 3.3.6.1, I get the following results from the timer:

[0]|0

[1]|20.4354662473683-Before

[2]|21.2189856887775-After

[3]|22.2542026075859-Before

[4]|23.0110717278588-After

[5]|23.6625240223034-Before

[6]|24.3080540231621-After

[7]|24.9050212166168-Before

[8]|25.7246666488998-After

[9]|26.5910982005111-Before

[10]|27.2999967427385-After

[11]|27.8566923398094-Before

[12]|28.6733766252994-After

[13]|29.3947119840572-Before

[14]|30.1900760126382-After

[15]|30.8480428300272-Before

[16]|31.6771639320476-After

[17]|32.2800534190881-Before

[18]|32.8977486400933-After

[19]|33.9163831368612-Before

[20]|34.6702911103412-After

[21]|35.3857041755131-Before

[22]|36.1603401765436-After

[23]|37.1523243521751-Before

[24]|37.7427770226853-After

[25]|38.3640256198421-Before

[26]|39.0356137124786-After

[27]|39.710162951908-Before

[28]|40.5564587053274-After

[29]|41.2345613209084-Before

[30]|42.0624979642116-After

[31]|42.3941464050197

Can anyone analyze these results and suggest a fix?

Just for the record, I'm running this on Intel i7 with 4Gigs of RAM.

Edited by trancexx
Forum rules forbid this kind of automation
Link to comment
Share on other sites

I haven't seen a fix yet but this is about the 3rd time i've seen it reported. I'm sure the devs must be aware of the issue by now.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

... that COM speed has went down and that it is the price we all must pay for doing it right.

Uhhh, does that mean there's no hope even with ticket #2037 still pending? Relying heavily on COM objects my vote then would be to do it wrong again...
Link to comment
Share on other sites

Eventually performance will be improved some but it is unlikely it will be as fast as it was before. We can go back to doing things wrong but then certain things don't work. Little things like IE9 not allowing forms to be submitted. You know, things people totally don't use ever.

Suggesting you'd rather do it wrong because it's faster is just plain stupid. Disappointed that an MVP said that but whatever.

Edit: Added the word "eventually" to express that performance will improve but not soon. The entire COM implementation will be re-written and re-optimized at some point but it is not a change that will be in 3.3.8.

Edited by Valik
Link to comment
Share on other sites

AdmiralAlkex, thank you for the info. I tried searching the forum and the bug reports but I have not found these posts. Probably I've not used the correct search terms.

trancexx, I was not aware of such restriction, otherwise I would have used another site. Can you please point me to the source of this restriction so I can inform myself better? :oops:

So if I understand Valik's post correctly, this is not a bug, but actually the right way it should work and from now on it will stay that way. I sure wish this wasn't the case, but I guess wishes should be sent to Santa, right? :rip:

It was nice talking to you guys! Keep up the excellent work and I'll try to keep the donations coming. After all currently I make my living with AutoIt. :D

Link to comment
Share on other sites

Additionally, I'll say that we know exactly why, when and what causes the issue.

If you would feel better, the problem is not COM wide. Only some Automation objects are really affected, primarily those built on latest ATL grounds.

Code can be just a bit tweaked for the next stable version, but anything else is obviously not an option.

@dv8,

Edited by trancexx
Link to comment
Share on other sites

If you would feel better, the problem is not COM wide. Only some Automation objects are really affected, primarily those built on latest ATL grounds.

Actually it makes me feel better as I rely heavily on the scripting dictionary object. For this object there seems to be no (large) difference between 3.3.6.1 and 3.3.7.20.

$oDictIcon = ObjCreate('Scripting.Dictionary')
$oDictIcon.CompareMode = 1
$timer = TimerInit()
for $i=0 to 100000
    $oDictIcon.Add($i, "999")
Next
$oDictIcon.RemoveAll()
$oDictIcon = 0
ConsoleWrite(TimerDiff($timer) & @crlf)
Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share

  • Recently Browsing   0 members

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