funkey Posted January 22, 2013 Share Posted January 22, 2013 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. expandcollapse popupExample1() 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 tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
Richard Robertson Posted January 22, 2013 Share Posted January 22, 2013 Pointer to variant isn't useful because the AutoIt variant is likely very different from any other knowable variant. Pointer to specific type makes sense when making dll calls because the dll was already designed for that. Link to comment Share on other sites More sharing options...
funkey Posted January 23, 2013 Author Share Posted January 23, 2013 (edited) 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 expandcollapse popup#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 January 23, 2013 by funkey Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
Richard Robertson Posted January 23, 2013 Share Posted January 23, 2013 sizeof(VARIANT) only works if you have a copy of the AutoIt variant, which you don't. That was the point I was trying to make. Link to comment Share on other sites More sharing options...
matwachich Posted February 18, 2013 Share Posted February 18, 2013 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 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