Release 4 and later of SmartArrays provides a means for .NET and C++ programmers to access the data in an SmArray object This facility is not available in SmartArrays for Java because the Java language has no pointer facility.
In SmartArrays for .NET, the address of the data in an SmArray object is exposed by four attributes of the SmArray object.
| C# Attribute | Use |
|---|---|
| DataPtrByte | An unsafe byte pointer to the array data |
| DataPtrChar | An unsafe char pointer to the array data |
| DataPtrInt | An unsafe int pointer to the array data |
| DataPtrDouble | An unsafe double pointer to the array data |
These provide access to the insides of arrays of appropriate types. Each ensures that the array is of the appropriate type. For example, DataPtrInt only works on arrays of type dtInt, for any other type of array it returns zero. Boolean arrays can be accessed one byte at a time via DataPtrByte; bits in a dtBoolean array are stored from high-order bit to low-order bit. Complex number arrays are stored internally as successive pairs of doubles, so DataPtrDouble can be used. No way is provided to access dtString, dtNested, or dtMixed data, as these arrays contain values that can be understood only inside the SmartArrays engine.
Used with appropriate care, these pointers allow data values in an array to be read or written at full speed, without incurring the overhead associated with SmArray method calls. They can let you achieve major performance improvements in situations where scalar-oriented custom logic needs to be applied to data in SmArray objects.
Working with SmArray data pointers does not require the C# fixed statement facility (which temporarily pins managed objects to their location in memory) because SmartArrays data is outside the scope of .NET memory management. As currently implemented, SmartArrays keeps its data blocks at a stable location for the lifespan of the array. The .NET instances of class SmArray do not need to be pinned because they hold only the handle that identifies an array to the engine.
The C# compiler must be called with the /unsafe switch to enable the use of unsafe code. In Visual Studio, you can set this in the Configuration Properties for the project by setting Allow Unsafe Code Blocks to true.
// Work with the contents of an SmArray as a unsafe int[] array.
// For example: replace each value in an array with its square
SmArray v = SmArray.sequence( 1000 );
unsafe {
int* vdata = v.DataPtrInt;
// now vdata can be used like an int[]
int vcount = v.getCount();
for ( int i=0; i<vcount; i++ )
vdata[i] *= vdata[i];
}
v.show();
0 1 4 9 16 25 36 ...
In SmartArrays for C++, the data is exposed a public method of class SmArray
| C++ Method | Use |
|---|---|
| void* getDataPtr() | A pointer to the array data |
| int* getDataPtrInt() | A pointer to the array data in an integer type array |
| char* getDataPtrChar() | A pointer to the array data in a dtByte type array |
| wchar* getDataPtrWChar() | A pointer to the double byte array data in a dtChar type array |
| double* getDataPtrDouble() | A pointer to the array data in a dtDouble type array |
These methods return a pointer to the array's data values. getDataPtr() returns a void*, which you can cast to the appropriate type based on array's internal data type. The type-specific methods are preferable because they enforce the array type. For example, getDataPtrInt() will throw an SA_CANNOT_CONVERT exception if the array is not integer type. The usage and guidelines are the same as those described above for .NET
// Work with the contents of an SmArray as an int[] array.
// For example: replace each value in an array with its square
SmArray v = SmArray::sequence( 1000 );
int* vdata = v.getDataPtrInt();
// now vdata can be used like an int[]
int vcount = v.getCount();
for ( int i=0; i<vcount; i++ )
vdata[i] *= vdata[i];
v.show();
0 1 4 9 16 25 36 ...