This short guide explains how arrays of structs are passed between managed C# code and native C++ using the eCLR. It follows the same patterns as numeric arrays and string arrays, with additional attention to nested fields (e.g., IEC strings) inside structs.
- Arrays are passed as pointers and must be declared as [InOut] to allow native code to read and modify them.
- A [Native] method wrapper (StructArrayFB1NativeMethods) is invoked from managed code using ref parameters to expose the array storage to native code.
StructArrayFB1NativeMethods-cli.cpp
- Methods are exposed to managed code via the PInvoke prefix.
- Elements are accessed through the array’s Anchor; size is determined via GetLowerBound/GetUpperBound.
- For struct fields:
- Copy scalar fields directly.
- For IEC string members inside the struct, copy contents using Assign(Begin(), GetLength()) rather than raw memory operations.
- A [Native] function block can implement its logic entirely in native code; only explicitly marked [Managed] members (e.g. __Init) run in C#.
- PInvoke is used for the __Process method to bridge calls from managed to native.
- Uses the same access pattern: null-check pointers, use Anchor for element data, and bounds to determine size.
- Copies struct fields appropriately, using Assign for any IEC string members.
- Contains an auto-generated ctor bridge; this is standard boilerplate for native FB classes.
- Arrays must be pointers and marked [InOut] for native read/write access.
- Always null-check array pointers before use in native code.
- Use GetLowerBound/UpperBound to compute array size; do not assume zero-based indexing.
- Treat structs as contiguous memory with a layout consistent between managed and native definitions.
- For nested IEC strings within structs, use Assign(Begin(), GetLength()) to copy content safely.
- The [Native] attribute and the PInvoke prefix define the managed–native boundary and enable seamless interop.