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;
int numbers[5];
for (int i = 0; i < 5; 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.