version 2003
PA_NewHandle (len) PA_Handle
Parameter | Type | Description | |
len | long | Size in bytes of the PA_Handle | |
Function result | PA_Handle | Returns the allocated handle |
Description
The routine PA_NewHandle allocates handleSize bytes in memory and returns a handle (of type PA_Handle). If an error occurred, PA_NewHandle returns 0.
NOTE for MacOS developers
The allocated handle can be manipulated like a "regular" Macintosh handle.
PA_Handle is defined as char** in PublicTypes.h, and this structure is used internally by the API (Pictures, BLOBs, etc.).
For example, once the plug-in received a PA_Handle from a BLOB, it can use PA_GetHandleSize to get its size and the * symbol on that handle to access the pointer:
PA_Handle myBlob; char *copied; long size; // get the handle myBlob = PA_GetBlobHandleParameter(params, 1); // get its size size = GetHandleSize(myBlob); // allocate the buffer copied = malloc(size); // use the * operator to give a valid argument to memmove memmove( (char *) copied, (char *) *myBlob, size);
The routines of the "4D Handles" theme are given to help the developer manipulate the PA_Handle returned by some entry points (Pictures, BLOB, etc.). They should not be used as a replacement for MemoryManager's OS routines (malloc, NewHandle, etc.)
Thus, as demonstrated in an example below, using those routines can be useful in some cases.
As it is defined as char**, developers have to use double-dereferencing to access the data :
(*handle)-> | |
or | (**handle). |
Once the handle is no longer needed, the developer should dispose of it by using PA_DisposeHandle. If the code that uses the handle can move memory, the developer should lock the handle using PA_LockHandle, run its code, and then unlock the handle by calling PA_UnlockHandle.
To get the actual size of a handle, call PA_GetHandleSize, and to resize it use PA_SetHandleSize.
As with any calls that allocate or touch memory, an error check should be conducted immediately after calling PA_NewHandle to see if the call failed (insufficient memory, etc).
Examples
(1) Allocating a new block of 1024 bytes in memory.
aHandle = PA_NewHandle(1024); if(aHandle == 0L) { // we've got a problem... } else { ... }
(2) Allocate a buffer and dispose of it after use.
aHandle = PA_NewHandle(MY_BUFFER_SIZE); if(aHandle == 0L) { // we've got a problem... } else { /*. . . working with the buffer . . .*/ // free the memory: PA_DisposeHandle(aHandle); }
(3) Initialize a handle with 0s.
PA_Handle myNewHandleClear (long size) { PA_Handle h = 0L; register long i; char* pt; h = PA_NewHandle(size); if ( h ) { pt = *h; for ( i = 0; i < size; i++ ) *pt++ = 0; } return h; }
(4) Initialize the data used by an external area.
// Structure used by each area typedef struct { char docName[256]; // Current document name char isDirty; // document was modified (need to be saved) /* . . . other fields . . . */ } AreaData, *AreaDataPtr, **AreaDataHandle; short InitMyArea(AreaDataHandle *data) { short err; AreaDataPtr p; // Allocate the memory *data = PA_NewHandle( sizeof(AreaData) ); // if no error, initialize it if(*data) { p = PA_LockHandle(*data); p->docName[0] = (char) 0; p->iDirty = (char) 0; /* . . . initialize the other fields . . . */ PA_UnlockHandle(*data); } return PA_GetLastError(); }
See Also
PA_DisposeHandle, PA_GetHandleSize.
Error Handling
Use PA_GetLastError to see if an error occurred (insufficient memory, etc.).