Skip to content

Latest commit

 

History

History
40 lines (29 loc) · 2.28 KB

File metadata and controls

40 lines (29 loc) · 2.28 KB

Interaction between Native and Managed Code for Arrays with Structs

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.

C# Class

StructArrayFB1.cs

  • 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.

Native Implementation

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.

C# Function Block

StructArrayFB2.cs

  • A [Native] function block can implement its logic entirely in native code; only explicitly marked [Managed] members (e.g. __Init) run in C#.

Native Implementation

StructArrayFB2-cli.cpp

  • 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.

Notes and Best Practices

  • 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.