Store PLCnext CommunityPLCnext on LinkedInPLCnext on Instagram  PLCnext on YouTube Github PLCnext CommunityStore PLCnext Community

  1. Rob H
  2. PLCnext Technology & PLCnext Controls
  3. Friday, 26 October 2018

I would like to return a ushort[] from a C# FB. My thought was I could do this using a DataType of "ANY" in the FB: 

   [Output, DataType("ANY")]

   public ushort[] Result;

 

Then in PCWE I created the following data type:

    RegisterArray : ARRAY[0..100] of UINT;

 

That resulted in an error, "operation not legal in this context". Is it possible to return an array from a C# FB?

Automation Engineer - Grand Rapids, MI, USA

Accepted Answer
Martin PLCnext Team Accepted Answer Pending Moderation
0
Votes
Undo

Hi Rob,

I've just realised that community member Björn posted a good answer to a similar question a few months ago:

https://plcnext-community.net/index.php?option=com_easydiscuss&view=post&id=903&Itemid=224&lang=en

Here's how you might declare the array in your specific case (put this in your source file before the class definition) - including comments that I hope are useful.

    // Declare User-Defined types that can be used in IEC 61131 programs.
    //
    // Notes:
    //  - The definition of these types is not visible in PLCnext Engineer,
    //    so separate user documentation is important.
    //  - If a PLCnext Engineer project uses two libraries that define data types with the same name,
    //    then that PLCNE project will not compile. Define data types with names that are likely to be unique.
    //  - This uses unsafe code, so the "Allow unsafe code" option must be checked in
    //    the Project Properties window (Project -> Properties -> Build).
    //
    // IecArrays must be defined as a struct with a fixed size.
    // The array definition MUST have following Attributes:
    // 1. Array (Currently only one-dimensional arrays are supported by PLCnext Engineer)
    // 2. DataType of the array elements
    // 3. ArrayDimension, specifying the upper and lower bounds of each dimension
    // The size of the struct is calculated by: (size of single element) x (total number of elements)

    [Array(1), DataType("UINT"), ArrayDimension(0, 0, 100)]
    [StructLayout(LayoutKind.Explicit, Size = 202)]
    public struct MY_ARRAY
    {
        // Fields
        // The field "Anchor" defines the beginning of the array.
        // The value of the FieldOffset attribute must always be zero.
        [FieldOffset(0)]
        // The Anchor's data type is the child data type of the array.
        public ushort Anchor;
        // The constants LB and UB define the upper and lower bound.
        public const int LB = 0;
        public const int UB = 100;
        // 'this' function must return the data type of the array.
        public ushort this[int index]
        {
            get
            {
                if ((index >= LB) && (index <= UB))
                {
                    unsafe
                    {
                        fixed (ushort* pValue = &Anchor)
                        {
                            byte ushort = *(pValue + index - LB);
                            return result;
                        }
                    }
                }
                else
                {
                    throw new IndexOutOfRangeException();
                }
            }
            set
            {
                if ((index >= LB) && (index <= UB))
                {
                    unsafe
                    {
                        fixed (ushort* pValue = &Anchor)
                        {
                            *(pValue + index - LB) = value;
                        }
                    }
                }
                else
                {
                    throw new IndexOutOfRangeException();
                }
            }
        }
    }

 

You would then declare your output variable as:


[Output, DataType("MY_ARRAY")]
public MY_ARRAY Result;

 

In PC Worx Engineer, you must then declare a variable of type MY_ARRAY to connect to this FB parameter. This data type is imported with your library, so there's no need to create a new Data Type for this in PCWE.

- Martin.

Phoenix Contact Electronics Headquarters - PLCnext Runtime Product Management and Support

Martin PLCnext Team Accepted Answer Pending Moderation
0
Votes
Undo

Hi Rob, sorry for the delay.

It is possible to pass both arrays and structures as parameters on a C# FB.

This is not documented in the Help files yet, but I have some sample code that I will post here tomorrow (Thursday) when I'm back in the office. It's not trivial but basically you will define the structure (or array) in your C# code as a user-defined type, using an Unsafe block of code to access memory using pointers. This custom type will be exported with your FB and you can then use this type to declare variables in PC Worx Engineer.

You could also use the general ANY data type to pass an array - in this case the variable in the C# code must also be declared as type Any (not ushort[]) and you must then use unsafe code to access data in the ANY variable using pointers ... and just trust that the caller is using the expected data type on their side. This is not as neat as defining your own array type and forcing the caller to use that type when calling your FB.

- Martin.

 

Phoenix Contact Electronics Headquarters - PLCnext Runtime Product Management and Support

  • Page :
  • 1


There are no replies made for this post yet.
However, you are not allowed to reply to this post.