Modify

Opened 6 years ago

Closed 6 years ago

#2860 closed Feature Request (Completed)

Convert UDF's ptr to struct* type

Reported by: Eukalyptus Owned by: Jpm
Milestone: 3.3.13.20 Component: Standard UDFs
Version: Severity: None
Keywords: Cc:

Description

there are still a lot of DllCall´s where "ptr" is used.
e.g. _WinAPI_UpdateLayeredWindow or _WinAPI_WaitForMultipleObjects

I think that it is no problem to change every "ptr" (except return type ;)) to "struct*", so the User can pass a struct directly without DllStructGetPtr.

thx

Attachments (0)

Change History (9)

comment:1 Changed 6 years ago by TicketCleanup

  • Version 3.3.12.0 deleted

Automatic ticket cleanup.

comment:2 Changed 6 years ago by Jpm

To have no script breaking both type should be accepted as in _WinAPI_WideCharToMultiByte()

Can post an exhaustive list of what to be changed?
Thanks

comment:3 Changed 6 years ago by anonymous

Is this really a script breaking change?!
If "struct*" is used instead of "ptr", the old behavior is preserved:

#include <Memory.au3>

Global $tSrc = DllStructCreate("byte[16];")
DllStructSetData($tSrc, 1, "0x11223344556677881122334455667788")
Global $tDst1 = DllStructCreate("byte[16];")
Global $tDst2 = DllStructCreate("byte[16];")
Global $tDst3 = DllStructCreate("byte[16];")

_MemMoveMemory(DllStructGetPtr($tSrc), DllStructGetPtr($tDst1), DllStructGetSize($tSrc))
ConsoleWrite("> " & DllStructGetData($tDst1, 1) & @CRLF)

_MemMoveMemory(DllStructGetPtr($tSrc), $tDst2, DllStructGetSize($tSrc))
ConsoleWrite("> " & DllStructGetData($tDst2, 1) & @CRLF)

_MemMoveMemory($tSrc, $tDst3, DllStructGetSize($tSrc))
ConsoleWrite("> " & DllStructGetData($tDst3, 1) & @CRLF)

Do you know an example, where I am forced to use "ptr"? (except DllCall-Return or ByRef "ptr*")
I use "struct*" all the time in DllCall and ObjCreateInterface and I´ve never noticed a disadvantage

Check it out:
Run this script in the include-folder.
It will make the change for testing. (It will backup the files, but be carefull anyway ;))

#include <File.au3>

$aFiles = _FileListToArray(@ScriptDir, "*.au3")
DirCreate(@ScriptDir & "\_BackUp")
For $i = 1 To $aFiles[0]
	If $aFiles[$i] = @ScriptName Then ContinueLoop
	ConsoleWrite("> " & $i & "/" & $aFiles[0] & " " & $aFiles[$i] & @CRLF)
	FileCopy(@ScriptDir & "\" & $aFiles[$i], @ScriptDir & "\_BackUp\" & $aFiles[$i])
	_Ptr2Struct($aFiles[$i])
Next


Func _Ptr2Struct($sFile)
	Local $hFile = FileOpen($sFile)
	Local $sUDF = FileRead($hFile)
	FileClose($hFile)

	Local $sNew = ""
	Local $aRegExp, $iOffset = 1
	While 1
		$aRegExp = StringRegExp($sUDF, "(?i)(dllcall)\h*(?=\()", 1)
		If @error Then ExitLoop
		$iOffset = @extended-1

		$sNew &= StringLeft($sUDF, $iOffset)
		$sUDF = StringTrimLeft($sUDF, $iOffset)

		$aRegExp = StringRegExp($sUDF, "\((?:[^()]*|(?R))*\)", 1)
		$sUDF = StringRegExpReplace($sUDF, "\((?:[^()]*|(?R))*\)", Chr(1), 1)
		$sUDF = StringReplace($sUDF, Chr(1), __Ptr2Struct($aRegExp[0]))

	WEnd
	$sNew &= $sUDF

	FileSetAttrib($sFile, "-R")
	Local $hFile = FileOpen($sFile, 2)
	FileWrite($hFile, $sNew)
	FileClose($hFile)
	FileSetAttrib($sFile, "+R")
EndFunc


Func __Ptr2Struct($sLine)
	$sLine = StringRegExpReplace($sLine, "(?m)^\(|\)$", "")
	Local $aRegExp = StringRegExp($sLine, "\((?:[^()]*|(?R))*\)", 3)
	$sLine = StringRegExpReplace($sLine, "\((?:[^()]*|(?R))*\)", Chr(3))

	$sLine = StringRegExpReplace($sLine, "(?mi)^([^,]+,\h*['" & '"]\h*)ptr(["' & "'])", "$1" & Chr(2) & "$2")
	$sLine = StringRegExpReplace($sLine, "(?i)['" & '"]\h*ptr\h*["' & "']", '"struct*"')

	For $i= 0 To UBound($aRegExp)-1
		$sLine = StringReplace($sLine, Chr(3), $aRegExp[$i], 1)
	Next

	Return "(" & StringReplace($sLine, Chr(2), "ptr") & ")"
EndFunc

comment:4 Changed 6 years ago by Jpm

The _MemMoveMemory example does not illustrate what you mean.
just try this one which is using ptr instead of struct*

#include <Memory.au3>

Global $tSrc = DllStructCreate("byte[16];")
DllStructSetData($tSrc, 1, "0x11223344556677881122334455667788")
Global $tDst1 = DllStructCreate("byte[16];")
Global $tDst2 = DllStructCreate("byte[16];")
Global $tDst3 = DllStructCreate("byte[16];")

_MemMoveMemory_(DllStructGetPtr($tSrc), DllStructGetPtr($tDst1), DllStructGetSize($tSrc))
ConsoleWrite("> " & DllStructGetData($tDst1, 1) & @CRLF)

_MemMoveMemory_(DllStructGetPtr($tSrc), $tDst2, DllStructGetSize($tSrc))
ConsoleWrite("> " & DllStructGetData($tDst2, 1) & @CRLF)

_MemMoveMemory_($tSrc, $tDst3, DllStructGetSize($tSrc))
ConsoleWrite("> " & DllStructGetData($tDst3, 1) & @CRLF)

Func _MemMoveMemory_($pSource, $pDest, $iLength)
	DllCall("kernel32.dll", "none", "RtlMoveMemory", "ptr", $pDest, "ptr", $pSource, "ulong_ptr", $iLength)
	If @error Then Return SetError(@error, @extended)
EndFunc   ;==>_MemMoveMemory

comment:5 Changed 6 years ago by Jpm

  • Resolution set to Rejected
  • Status changed from new to closed

comment:6 Changed 6 years ago by eukalyptus

Your example crashes at the second _MemMoveMemory_ !
(And so it illustrates what I mean...)

comment:7 Changed 6 years ago by Jpm

You right it is crashing but you just demonstrate that ptr should not be assimilate to struct*
at least for _MemMoveMemory() we cannot use 'struct*' as this function must work with ptr that are not dllstruct

I will investigate if some other functions can be change from ptr to struct*

comment:8 Changed 6 years ago by Jpm

  • Resolution Rejected deleted
  • Status changed from closed to reopened

I understand better your idea.
A lot of change to do.
I will convert 'ptr' to 'struct*' when $tag... can be used

comment:9 Changed 6 years ago by Jpm

  • Milestone set to 3.3.13.20
  • Owner set to Jpm
  • Resolution set to Completed
  • Status changed from reopened to closed

Added by revision [11085] in version: 3.3.13.20

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 closed The owner will remain Jpm.
Author


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

 
Note: See TracTickets for help on using tickets.