AutoFreePtr, Ptr Property

Requires: GfaWinx.lg32

Purpose

Creates a simple COM object that wraps a handle or pointer to call either a predefined API or a user-defined callback procedure to free the handle or pointer.

Syntax

Set obj = AutoFreePtr(handle, ProcAddr(procname) | constant)

constant: predefined Int32 constant
P = obj.Ptrhandle: integer of Handle expression
obj: Object variable
procname: the name of a callback procedure
p: integer

Description

AutoFreePtr can be used in two ways: through a predefined constant which will delete a specific object once it goes out of scope using a predefined destruction function; or through a user-defined clean up procedure which can be written to clean up one or more pointers as required.

The object returned by AutoFreePtr calls the specified predefined function or procname procedure when the object goes out of scope to free the handle or pointer. If the object is a local variable, the call back procedure is called when the subroutine ends. For a global object variable the call back procedure is called when the application is closed. Instead of using AutoFreePtr you might prefer to use the App_Close event to release global resources.

The Int32 handle parameter will contain a Handle or a pointer (address) to an object if a constant is used as a second parameter. However, if calling a user-defined procedure, any 32-bit value can be passed, the meaning of the value being determined in the call back procedure.

The available constants are:

The call back procedure takes one ByVal argument of type Int32, the value that is set when the object is created and the signature of the procedure is:

Sub MyFreeHandler(ByVal ptr as Integer)

The procaddr parameter must specify a procedure in the program. The parameter can be 0, in which case the passed in value will be used in a call to the CloseHandle() API. So, if the handle parameter is an API handle that needs to be released with CloseHandle, the ProcAddr can be set to 0.

The AutoFreePtr object has one property, the Ptr GET/PUT property. The Ptr property returns the 32-bit value passed when the object is created (see example 2); it is also possible to set this property, for example if a pointer to a memory block is changed after it is resized using mReAlloc or mShrink.

Examples

Example 1 (Pseudocode)

OpenW 1

Local threadID As Long

' API function, handle must be closed when finished

Global Handle hThread = CreateThread(Null, 0, ProcAddr(ThreadProc), 0, 0, V:threadID)

Global ohThread As Object

' Close handle in application defined call back sub:

Set ohThread = AutoFreePtr(hThread, ProcAddr(DoCloseHandle))

' or Set ohThread = AutoFreePtr(hThread, 0)  ‘ calls CloseHandle() automatically

Do

Sleep

Until Me Is Nothing

' No call to CloseHandle() here! ohThread object goes out

' of scope and calls DoCloseHandle() automatically.

 

Sub DoCloseHandle(ByVal h As Int)

' If thread h is still running, either give it some more time,

' call TerminateThread(h,0)

If WaitForSingleObject(h, 0) == WAIT_TIMEOUT // thread's state is non-signaled (still running)

~TerminateThread(h, 0)

EndIf

~CloseHandle(h)

EndSub

 

Procedure ThreadProc

' Code for new thread

EndProcedure

Example 2

$Library "gfawinx"

$Library "UpdateRT"

UpdateRuntime      ' Patches GfaWin23.Ocx

Global Object oMemPtr1, oMemPtr2

' Alloc memory, and create an AuoFreePtr COM wrapper object

Global Int pm1 = mAlloc(100)    ' might be local as well

Set oMemPtr1 = AutoFreePtr(pm1, ProcAddr(FreeMem))

' Alloc memory and encapsulate in AutoFreePtr object directly:

Set oMemPtr2 = AutoFreePtr(mAlloc(100), ProcAddr(FreeMem))

Local Int pm2 = oMemPtr2.Ptr  ' obtain pointer through property

' The callback proc that releases the memory

 

Proc FreeMem(ByVal ptr As Long)

~mFree(ptr)

Debug "Freeing Memory: ";Hex(ptr)

EndProc

Remarks

See Also

OnAppClose

{Created by Sjouke Hamstra; Last updated: 08/07/2023 by James Gaite; Other Contributors: Jean-Marie Melanson}