Match Array from C# Program to GDS Port

Hello,
I have found some similar issues in the forums but I cannot seem to find an exact answer to my question regarding this issue.
My problem is I want to define a C# array for example bool myArray[2] and then connect the seperate variables to actual IO in GDS Port List in PLCnext Engineer.
For example:
myArray[0] → Digital_Output1
myArray[1] → Digital_Output2


What I have done is copy the following code from the C# Examples in Github and then declare my array like this into my C# PROGRAM:
[Global, OutputPort, DataType(“IntArrayFB”)]
public IntArrayFB IN_ARRAY;

This is only a test “Int” Array before I try to do what I previously explained.
After that I add my library to the PLCnext Engineer but in the GDS Port I see the following:
image.pngThere appear to be 3 weird errors. Also I only see “IN_ARRAY” instead of two seperate variables “IN_ARRAY[0]” and “IN_ARRAY[1]” and when I press the “IN PORT” no plc variables appear to connect them into it. Have I not understood something correctly?
Thank you in advance once again for your time and effort you put into my issue.


C# Code:
// 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 the PCWorx Engineer)
// 2. ArrayDimension
// 3. DataType to define the data type of the array elements
[Array(1), ArrayDimension(0, ArrayProperties.LowerBound, ArrayProperties.UpperBound), DataType(“DINT”)]
[StructLayout(LayoutKind.Explicit, Size = ArrayProperties.ByteSize)]
public struct IntArrayFB
{
// Helper containing constants to have a
// clear and maintainable definition for boundaries and size
private struct ArrayProperties
{
public const int LowerBound = 0; // must not necessarily being zero, it also can be negative
public const int UpperBound = 1; // IEC61131 representation is : userArray : ARRAY[-10..9] OF DINT (* 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) * sizeof(int);
}

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 int 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 int this[int index]
{
get
{
if (index >= (LB - ArrayProperties.LowerBound) && index <= (UB - ArrayProperties.LowerBound))
{
unsafe
{
fixed (int* pValue = &Anchor)
{
int result = (pValue + index);
return result;
}
}
}
else
{
throw new IndexOutOfRangeException();
}
}
set
{
if (index >= (LB - ArrayProperties.LowerBound) && index <= (UB - ArrayProperties.LowerBound))
{
unsafe
{
fixed (int
pValue = &Anchor)
{
*(pValue + index) = value;
}
}
}
else
{
throw new IndexOutOfRangeException();
}
}
}
}

[Global, OutputPort, DataType(“IntArrayFB”)]
public IntArrayFB IN_ARRAY;

When you click in the empty space in the OUT Port column, opposite the INT variable you want to connect to, do you see the individual array elements, like this?

No I do not see it unfortunately. See the screenshot attached.


But also the above code I sent you created these 3 weird errors.

For me, the individual array elements do appear in PLCnext Engineer.
Here’s what I did:


* Created a new C# library in Visual Studio.
* Added a C# Function Block.
* Copied and pasted the source code from the Array example in Github.
* Built the project.
* Added the PLCnext Engineer library to an empty PLCnext Engineer project.
* In the Main program, added an OUT port variable of type IntArrayFB, and an IN port variable of type DINT.
* The individual OUT port array elements now appear in the GDS Port list, opposite any IN variable with the correct type:
Does that procedure work for you?
If so, hopefully it will help you to identify what is different in your project.

This actually worked like a charm.
So if I want to create an array of BOOL for example I just change the DataType from DINT to BOOL I suppose.
Thank you once again!

So if I want to create an array of BOOL for example I just change the DataType from DINT to BOOL I suppose.It’s not quite that simple, unfortunately …
Array definitions in C# map the IEC type to the C# type - in the example that’s DINT <=> int. You can see in the example that there are int variables and pointers used at various places in the array definition. You will need to understand each of those variables and pointers, and adapt these to the type of your array.
The mapping between IEC and C# types is given in the Readme file that is included in each Visual Studio project:

+-------------------+--------------------------------+--------+-----------+
| IEC 61131-3    | .NET Framework         | C#   | DataType |
|          |                |    | Attribute |
+-------------------+--------------------------------+--------+-----------+
|  BOOL      | System.Boolean         | bool  |   -   |
|  SINT      | System.SByte          | sbyte |   -   |
|  INT      | System.Int16          | short |   -   |
|  DINT      | System.Int32          | int  |   -   |

(etc).