Jump to content

Feature request VarGetPtr()


funkey
 Share

Recommended Posts

Hello,

i just made a function to get a pointer to the variable variant value. Of course it's very unstable to play with unknown memory areas and I don't know if this works everywhere. I tested on WinXP SP3 x86 and Win7 SP1 x64. What do you think about building in a function like this in AutoIt? I think this could be useful sometimes for example with byref values in DllCalls.

Example1()
ConsoleWrite(@CRLF)
Example2()
ConsoleWrite(@CRLF)
Example3()
;~ ConsoleWrite(@CRLF)
;~ Example4()

Func Example1()
    Local $iStart, $pTest, $tTest
    Local $fTest = 430.2

    $iStart = TimerInit()
    $pTest = _VarGetPtr($fTest)
    ConsoleWrite("Function duration: " & TimerDiff($iStart) & " msec" & @CRLF)

    $tTest = DllStructCreate("double", $pTest)

    ConsoleWrite("Old value: " & $fTest & @CRLF)
    DllStructSetData($tTest, 1, 666.789) ; set new value in variable
    ConsoleWrite("New value: " & $fTest & @CRLF)
EndFunc   ;==>Example1

Func Example2()
    Local $iStart, $pTest, $tTest
    Local $iTest = 415

    $iStart = TimerInit()
    $pTest = _VarGetPtr($iTest)
    ConsoleWrite("Function duration: " & TimerDiff($iStart) & " msec" & @CRLF)

    $tTest = DllStructCreate("int", $pTest)

    ConsoleWrite("Old value: " & $iTest & @CRLF)
    DllStructSetData($tTest, 1, 666) ; set new value in variable
    ConsoleWrite("New value: " & $iTest & @CRLF)
EndFunc   ;==>Example2

Func Example3()
    Local $iStart, $pTest, $tTest
    Local $hTest = Ptr(0x123456FF)

    $iStart = TimerInit()
    $pTest = _VarGetPtr($hTest)
    ConsoleWrite("Function duration: " & TimerDiff($iStart) & " msec" & @CRLF)

    $tTest = DllStructCreate("ptr", $pTest)

    ConsoleWrite("Old value: " & $hTest & @CRLF)
    DllStructSetData($tTest, 1, Ptr(0xBBBBBBBB)) ; set new value in variable
    ConsoleWrite("New value: " & $hTest & @CRLF)
EndFunc   ;==>Example3


Func Example4()
    Local $iStart, $pTest, $tTest

    Local $sTest = "This is a test string"

    $iStart = TimerInit()
    $pTest = _VarGetPtr($sTest)
    ConsoleWrite("Function duration: " & TimerDiff($iStart) & " msec" & @CRLF)

    $tTest = DllStructCreate("wchar[" & StringLen($sTest) + 1 & "]", $pTest)

    ConsoleWrite("Old Struct value: " & DllStructGetData($tTest, 1) & @CRLF)
    ConsoleWrite("Old value: " & $sTest & @CRLF)

    DllStructSetData($tTest, 1, "a", 2) ; set new value in variable

    ConsoleWrite("New Struct value: " & DllStructGetData($tTest, 1) & @CRLF)
    ConsoleWrite("New value: " & $sTest & @CRLF)
EndFunc   ;==>Example4

Func _VarGetPtr(ByRef $var)
    Local $tTest, $pTest, $tTest2, $i = -500, $Save = $var

    Switch VarGetType($var)
        Case "Int32"
            $var = 987654
            $tTest = DllStructCreate("int")
            $pTest = DllStructGetPtr($tTest)

            Do
                $i += 1
                $tTest2 = DllStructCreate("int", $pTest - $i)
            Until DllStructGetData($tTest2, 1) = $var

        Case "Double"
            $var = 1234.5678
            $tTest = DllStructCreate("double")
            $pTest = DllStructGetPtr($tTest)

            Do
                $i += 1
                $tTest2 = DllStructCreate("double", $pTest - $i)
            Until DllStructGetData($tTest2, 1) = $var

        Case "Ptr"

            $var = Ptr(0xFF777777)
            $tTest = DllStructCreate("ptr")
            $pTest = DllStructGetPtr($tTest)

            Do
                $i += 1
                $tTest2 = DllStructCreate("ptr", $pTest - $i)
            Until DllStructGetData($tTest2, 1) = $var

        Case "String"
            Local $tagTemp = "wchar[" & StringLen($var) + 1 & "]"
            $var = "Hello AutoIt"
            $tTest = DllStructCreate($tagTemp)
            $pTest = DllStructGetPtr($tTest)

            Do
                $i += 1
                $tTest2 = DllStructCreate($tagTemp, $pTest - $i)
            Until DllStructGetData($tTest2, 1) = $var

        Case Else
            $var = $Save
            Return 0
    EndSwitch

    $var = $Save

    Return $pTest - $i
EndFunc   ;==>_VarGetPtr

Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Link to comment
Share on other sites

If I could use pointers I could make faster inferfaces to DLLs, for example if I have an array with all integer or double values in it, I could pass a pointer to the first element and get the others by adding the 'sizeof(VARIANT)'. I know this works only with self written DLLs, but could be useful.

Of course more useful would be a function like DLLStructCreateFromAutoitIntegerArray or DLLStructCreateFromAutoitDoubleArray and back again like ArrayCreateFromDLLStruct.

Edit: Another example

#include <WinAPI.au3>

Global $sFile = @ScriptFullPath

Global $hFile = _WinAPI_CreateFile($sFile, 2, 2)
Global $tBuffer = DllStructCreate("char[" & FileGetSize($sFile) + 1 & "]")
Global $iRead = 0
_WinAPI_ReadFileEx($hFile, DllStructGetPtr($tBuffer), FileGetSize($sFile), $iRead)
_WinAPI_CloseHandle($hFile)
ConsoleWrite($iRead & " Bytes read" & @CRLF)


Func _WinAPI_ReadFileEx($hFile, $pBuffer, $iToRead, ByRef $iRead, $pOverlapped = 0)
    Local $aResult = DllCall("kernel32.dll", "bool", "ReadFile", "handle", $hFile, "ptr", $pBuffer, "dword", $iToRead, "ptr", _VarGetPtr($iRead), "ptr", $pOverlapped)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0]
EndFunc   ;==>_WinAPI_ReadFileEx


Func _VarGetPtr(ByRef $var)
    Local $tTest, $pTest, $tTest2, $i = -500, $Save = $var

    Switch VarGetType($var)
        Case "Int32"
            $var = 987654
            $tTest = DllStructCreate("int")
            $pTest = DllStructGetPtr($tTest)

            Do
                $i += 1
                $tTest2 = DllStructCreate("int", $pTest - $i)
            Until DllStructGetData($tTest2, 1) = $var

        Case Else
            $var = $Save
            Return 0
    EndSwitch

    $var = $Save

    Return $pTest - $i
EndFunc   ;==>_VarGetPtr
Edited by funkey

Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Link to comment
Share on other sites

  • 4 weeks later...

I have another example where VarGetPtr could be usefull for me:

- I have a 2DGameEngine made in a C DLL

- In this DLL, when I create for example a Sprite, it is done with malloc(sizeof(t_sprite))

- In the t_sprite structure, I have an element that can contain user defined data: a simple Integer

- Now, when I use this engin in AutoIt, it would be usefull to "attach" an AutoIt Array to my Sprite by setting the user defined data of the Sprite to the pointer of the AutoIt Array

For the moment, to attach data to my sprites, I allocate some DllStruct and pass the pointer to the user defined data of the sprite

But, I think the problem would be to recover the AutoIt var from a "simple" pointer...

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...