2

Im trying to read an alarm structure from a Beckhoff - PLC into a c# class. First i have to make the exact same structure in c# and it currently looks like this:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
    public class Alarm
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 81)]
        public string text;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
        public string objectName;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        public string[] instancePath = new string[6];
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 24)]
        public string timeStamp;
        public int priority;
        [MarshalAs(UnmanagedType.I1)]
        public bool acknowledge;
        [MarshalAs(UnmanagedType.I1)]
        public bool disabled;
        [MarshalAs(UnmanagedType.I1)]
        public bool alarmIn;
    }

Whats causing me problems is the "instancePath" field. When the field is a string i can use the "UnmanagedType.ByValTStr" attribute with SizeConst and when it's an array "UnmanagedType.ByValArray" but when i want to use a string[] i don't know what to do.

I've tried creating a new class:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
    public class InstancePathDefinition
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
        public string instancePath;
    }

And used in my alarm class:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
    public class Alarm
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 81)]
        public string text;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
        public string objectName;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        public InstancePathDefinition[] instancePath = new InstancePathDefinition[6];
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 24)]
        public string timeStamp;
        public int priority;
        [MarshalAs(UnmanagedType.I1)]
        public bool acknowledge;
        [MarshalAs(UnmanagedType.I1)]
        public bool disabled;
        [MarshalAs(UnmanagedType.I1)]
        public bool alarmIn;
    } 

But when I use Marshal.SizeOf on my Alarm-class it gives me a size or 147 bytes instead of 189 bytes as I would expect.

EDIT: I think the reason for the difference in size is that only the array gets initiated and the class "InstancePathDefinition" doesn't.

I tried changing it from a class to a struct and now the sizes match.

I still find it strange though that I can't combine both UnmanagedType.ByValArray and UnmanagedType.ByValTStr as a sub type with different SizeConst.

Next I will need to create an array of the alarm class and that will get me into the same trouble again.

7
  • You might try a fixed size char array instead (aka char[66]) Then you can put some helper fuctions in your class to extract the 6 strings you are looking for since they are at fixed offsets in the array. Commented Nov 4, 2011 at 15:21
  • Is the text data coming is a unicode or ascii in the data. If its ascii then you are going to need to set the character set as well. Commented Nov 4, 2011 at 15:40
  • Thanks user957902, Ive verified that i get the correct strings from the PLC so no need to change the character sets. Commented Nov 4, 2011 at 16:41
  • Where is the C++ declaration for the struct? Commented Nov 4, 2011 at 16:52
  • @user957902 P/invoke defaults to ANSI text Commented Nov 4, 2011 at 17:02

1 Answer 1

3

Make it an array of structures instead of an array of class objects.

[StructLayout(LayoutKind.Sequential)]
public struct InstancePathDefinition {
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
    public string path;
}

Marshal.SizeOf() returned 189 when I tried it.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.