using Iec61131.Engineering.Prototypes.Common; using Iec61131.Engineering.Prototypes.Methods; using Iec61131.Engineering.Prototypes.Pragmas; using Iec61131.Engineering.Prototypes.Types; using Iec61131.Engineering.Prototypes.Variables; using System; using System.Iec61131Lib; using System.Runtime.InteropServices; namespace T255347 { // The IecArray must be defined as a struct with a fixed size. // The array definition MUST have following Attributes: // 1. Array (Actually only one-dimensional arrays are supported by PLCnext Engineer) // 2. ArrayDimension // 3. DataType to define the data type of the array elements [Array(1), ArrayDimension(0, ArrayProperties.LowerBound, ArrayProperties.UpperBound), DataType("STRING")] [StructLayout(LayoutKind.Explicit, Size = ArrayProperties.ByteSize)] public struct StringArrayFB { // Helper containing constants to have a // clear and maintainable definition for boundaries and size private struct ArrayProperties { public const int LowerBound = -10; // must not necessarily being zero, it also can be negative public const int UpperBound = 9; // IEC61131 representation is : userArray : ARRAY[-10..9] OF STRING (* size == 20 *) // the size must be changed to the correct size of your elements times the amount of elements public const int ByteSize = (UpperBound - LowerBound + 1) * 86; } public const int ByteSize = ArrayProperties.ByteSize; // Fields // The field "Anchor" defines the beginning of the array. [FieldOffset(0)] // The Anchor's data type is the child data type of the array public IecString80 Anchor; // The constants LB and UB define the upper and lower bound. Boundaries will be checked by using them. public const int LB = ArrayProperties.LowerBound; public const int UB = ArrayProperties.UpperBound; public void Init() { unsafe { fixed (IecString80* ptr = &this.Anchor) { for (int i = 0; i < UB - LB + 1; i++) { ptr[i].ctor(); } } } } public IecString80 this[int index] { get { if (index >= (LB - ArrayProperties.LowerBound) && index <= (UB - ArrayProperties.LowerBound)) { unsafe { fixed (IecString80* pValue = &Anchor) { IecString80 result = *(pValue + index); return result; } } } else { throw new IndexOutOfRangeException(); } } set { if (index >= (LB - ArrayProperties.LowerBound) && index <= (UB - ArrayProperties.LowerBound)) { unsafe { fixed (IecString80* pValue = &Anchor) { *(pValue + index) = value; } } } else { throw new IndexOutOfRangeException(); } } } } [FunctionBlock] public class FunctionBlock1 { [Input] public short IN1; [Input] public short IN2; [Input] public StringArrayFB IN3; [Output, DataType("WORD")] public ushort OUT; [Output, DataType("STRING")] public IecString80 OUT1; [Initialization] public void __Init() { IN3.Init(); OUT1.ctor(); } [Execution] public void __Process() { OUT = (ushort)(IN1 + IN2); OUT1 = IN3[0]; } } }