C# Array Wrapper

The TS3D.Exchange.ArrayWrapper class, a static utility collection, simplifies interactions between C-style arrays and C# arrays. It provides functions to handle data conversion and copying, reducing boilerplate code and potential errors.

About Arrays in C and C#

Arrays are fundamental to both C and C#, but their nature differs significantly.

In C, arrays are low-level and managed via pointers. The syntax is straightforward but requires manual memory management. In C#, arrays are high-level and managed by the runtime, providing safety and bounds checking:

int[] numbers = new int[5];
for (int i = 0; i < numbers.Length; i++) numbers[i] = i * 2;

The HOOPS Exchange API extensively uses C-style arrays, which require manual memory management and direct manipulation. A bridge between these low-level C arrays and high-level C# arrays is essential, as managed arrays in C# offer better safety, simplicity, and performance.

The System.Runtime.InteropServices.Marshal class from the .NET API plays a crucial role in interacting with unmanaged code by facilitating conversions between managed and unmanaged data structures. This class provides the necessary tools for allocating memory, copying data, and ensuring proper memory management when working with interop scenarios.

For detailed information, refer to the official .NET documentation.

Reading and Writing Fundamental Types

Most arrays managed by HOOPS Exchange are sequences of integral types as described in Type Definitions. The following functions allow you to convert them from and to arrays in C# Integral Numeric Types.

Convert to C# Convert from C# Underlying Value Type Array Type (C#)
ReadIntArray WriteIntArray A3DInt32 int[]
ReadUIntArray WriteUIntArray A3DUns32 uint[]
ReadDoubleArray WriteDoubleArray A3DDouble double[]
ReadBoolArray WriteBoolArray A3DBool bool[]
ReadByteArray WriteByteArray A3DUns8 byte[]
ReadPtrArray WritePtrArray A3DVoid* IntPtr[]
ReadStructArray<T> WriteStructArray<T> T T[]
ReadStringArray WriteStringArray A3DUTF8Char* string[]

A lot of arrays in HOOPS Exchange are arrays of pointers. For example, arrays of entities, like A3DAsmModelFileData::m_ppPOccurrences. They are interpreted as IntPtr and thus can be accessed using ReadPtrArray and WritePtrArray.

Reading Into a C# Array

All read functions follow a similar signature:

static int[] ReadIntArray(IntPtr unmanagedArray, uint length)

Refer to the table above to adapt the function name and return type according to the array you are reading from.

For example, to get a list of child product occurrences and read them into an array of IntPtr, use:

A3DAsmProductOccurrenceData product_occurrence_data;
API.Initialize(out product_occurrence_data);

API.A3DAsmModelFileGet(product_occurrence_handle, ref product_occurrence_data);

IntPtr[] children_handles = ArrayWrapper.ReadIntPtrArray(
    product_occurrence_data.m_ppPOccurrences,
    product_occurrence_data.m_uiPOccurrencesSize
);

Writing Into Unmanaged Memory

All write functions follow a similar signature:

static IntPtr WriteIntArray(int[] array)

Refer to the table above to adapt the function name and parameter type according to the array you are reading from.

The inverse of the previous example can be written this way:

A3DAsmProductOccurrenceData product_occurrence_data;
API.Initialize(out product_occurrence_data);

IntPtr[] children_handles = ... ;

product_occurrence_data.m_ppPOccurrences     = ArrayWrapper.WritePtrArray(children_handles);
product_occurrence_data.m_uiPOccurrencesSize = children_handles.Length;

API.A3DAsmModelFileCreate(ref product_occurrence_data, out product_occurrence_handle);

Converting Arrays of Structures

It is possible to handle arrays of data structures using ReadStructArray<T> and WriteStructArray<T>.

These generic functions work similarly to the other functions, but they accept any structure binding (Struct.cs) and expect an underlying type T matching the structure’s name. For example, an A3DVector3DData[] can be converted to and from an array of A3DVector3DData using ReadStructArray<A3DVector3DData> and WriteStructArray<A3DVector3DData>.

Converting Arrays of String

In HOOPS Exchange, strings are encoded as null-terminated UTF-8 sequences of bytes (A3DUTF8Char). To convert to and from arrays of strings, use ReadStringArray and WriteStringArray.

Arrays and Wrapper Classes

If you are using C# Wrapper Classes instead of the C# Bindings, this conversion is abstracted away using Properties.