Scriptable Types

Scriptable methods are limited to using certain types including:

Unsigned char

Short

Long

Float

Double

BSTR

IDispatch

VARIANT

The BSTR type is the scriptable type for strings. There are two functions to allocate BSTRs: SysAllocString and SysFreeString.

| It is important to use these functions to avoid memory leaks and corruption.

The VARIANT type is a structure capable of holding any scriptable type as well as arrays of scriptable types. There are functions to initialize, copy, convert and clear VARIANTs:

VariantInit

VariantCopy

VariantChangeType

VariantClear

| It is important to use these functions to avoid memory leaks and corruption.

Arrays are held in SAFEARRAY structures containing information about the dimensions and bounds of an array, as well as a lockable pointer to the data.

| It is important to use the set of APIs surrounding SAFEARRAYs (like SafeArrayGetElement) to avoid memory leaks and corruption.

More about SAFEARRAYs

Safe arrays are data types specific to the Component Object Model (COM). They are just like normal C++ arrays except that they allow you to check the index that you pass against the upper and lower array bounds in order to reduce unnecessary errors. They also check that the pointer you are using is valid (by enabling locking and unlocking).

The bounds-checker functions are SafeArrayGetElement and SafeArrayPutElement which query the safe array object to find both its lower and upper bounds (since arrays dont have to be 0-based).

These are the basic structure of the safearray and the safearraybound types:

       typedef struct  tagSAFEARRAY
       {
           USHORT cDims;                  // number of dimensions
           USHORT fFeatures;              // flags for allocation type, data type
           ULONG cbElements;              // size of a single element
           ULONG cLocks;                  // lock counter
           PVOID pvData;                  // pointer to actual data block
           SAFEARRAYBOUND rgsabound[ 1 ]; // array of bounds structs
       }    SAFEARRAY;

       typedef struct  tagSAFEARRAYBOUND
       {
           ULONG cElements;
           LONG lLbound;
       }      SAFEARRAYBOUND;

Most scripting arrays are already safe arrays or are implicitly converted to safe arrays; however, if you are using C++ to develop your plug-in, you need to explicitly use safe arrays instead of normal C++ arrays. For more information on safe arrays and other data types for COM, see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnguion/html/drgui042099.asp.

| The order of safe arrays is opposite of standard C++ arrays. For example, the ControlPointCollection.Array property returns an array that is ordered like this: [U] [V] [X,Y,Z,W] (C++ array) [X,Y,Z,W] [V] [U] (Safe array)