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