Saving data from IPB_Value to a local variable
To avoid memory leaks,
you must call FreeCallInfo to free the values
stored in the PBCallInfo structure after using the structure. However,
after making a function call, you might want to save the return
value or a by reference argument value into a local variable you
can use later.
There are techniques for saving values so they are still available
after the call to FreeCallInfo. How you save
your result into a local variable depends on whether you want to
save a simple value, a pointer value, or an object value.
Saving simple values
Saving simple values is straightforward. When you call one
of the IPB_Value Get<type> methods
for a simple value, such as GetInt or GetReal,
the actual data is returned. As a result, you can simply save the
values of any of the following datatypes:
pbvalue_byte
pbvalue_int
pbvalue_uint
pbvalue_long
pbvalue_ulong
pbvalue_real
pbvalue_double
pbvalue_longlong
pbvalue_boolean
pbvalue_char
Saving pointer values
A pointer value does not contain data. It contains a pointer
to a memory location where the data is stored. When you call one
of the IPB_Value Get<type> methods
for a pointer value, such as GetBlob or GetTime,
it returns a pointer to memory that is also pointed to by IPB_Value.
When you call FreeCallInfo, the memory
to which IPB_Value points is released and the data is deleted.
Because this is the same data pointed to by the pointer returned
by the Get<type> method,
that pointer can no longer be used to represent the data.
This applies to the following pointer value datatypes, as
well as to the pbarray datatype:
pbvalue_dec
pbvalue_string
pbvalue_blob
pbvalue_date
pbvalue_time
pbvalue_datetime
If you want to save the data in a pointer value, you can use
the AcquireValue, AcquireArrayItemValue,
and ReleaseValue methods to acquire and release
the data.These methods clone a new IPB_Value that is not
freed until you call ReleaseValue and reset the
existing IPB_Value pointer.
Can be used for other datatypes You can use AcquireValue and AcquireArrayItemValue to
acquire values of any datatype.
Like the Get<type> methods, AcquireValue and AcquireArrayItemValue return
a pointer to the memory where the data is stored, but they also
reset the IPB_Value pointer so that IPB_Value
no longer points to the actual data. When you call FreeCallInfo,
the data pointed to by the value acquired using AcquireValue and AcquireArrayItemValue is
unaffected.
The original value is reset to zero or null,
so it can no longer be used. Attempts to get or acquire the original
value return zero or null until another IPB_Value is
set to the value.
If the IPB_Value acquired using AcquireValue is
an array, the entire array is acquired. To acquire only an element
of the array, use AcquireArrayItemValue. When
you have finished using the data, you must free the memory using
the ReleaseValue method.
The processing that the AcquireArrayItemValue and ReleaseValue methods perform
results in poor performance when handling large arrays. It is more efficient
to get the type of the array and handle each type with appropriate type–specific
functions.
Caution You must call the ReleaseValue method
to free the data. If you do not do so, a memory leak will occur.
You must not call ReleaseValue to
release a pointer that was not acquired using AcquireValue and AcquireArrayItemValue.
Doing so might cause the PBVM to crash.
Saving object values
Strictly speaking, object values are also pointer values,
but the PBVM handles them differently. You use the IPB_Session AddLocalRef and AddGlobalRef methods
to add a reference to the object. If there is a reference to an
object, it is not deleted when FreeCallInfo is
called.
When you no longer need the object, call RemoveLocalRef or RemoveGlobalRef to
decrease the reference count for the object. If the reference count
is decreased to zero, the object is deleted automatically.
There is an important difference between AddLocalRef and AddGlobalRef.
A reference added by AddLocalRef can be deleted
automatically when the local frame is popped up. The local frame
can be popped by calling PopLocalFrame or when
the current function returns. However, a reference added by AddGlobalRef is
deleted only when RemoveGlobalRef is called or
the session ends.
You must use these methods in pairs; that is, use RemoveLocalRef to
remove references created with AddLocalRef, and
use RemoveGlobalRef to remove references created
with AddGlobalRef.