MarshalAsAttribute字符串数组

时间:2011-11-04 13:19:40

标签: c# arrays string attributes marshalling

我试图从Beckhoff-PLC读取报警结构到c#类。 首先,我必须在c#中使用完全相同的结构,它目前看起来像这样:

[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;
    }

导致我出现问题的是“instancePath”字段。 当字段是一个字符串时,我可以使用带有SizeConst的“UnmanagedType.ByValTStr”属性,当它是一个数组“UnmanagedType.ByValArray”但是当我想使用字符串[]时,我不知道该怎么做。

我尝试过创建一个新类:

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

用于我的闹钟课程:

[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;
    } 

但是当我在Alarm-class上使用Marshal.SizeOf时,它给了我一个大小或147字节,而不是像我期望的那样189字节。

编辑: 我认为大小不同的原因是只有数组被启动而类“InstancePathDefinition”没有。

我尝试将它从类更改为结构,现在大小匹配。

虽然我不能将UnmanagedType.ByValArray和UnmanagedType.ByValTStr组合为具有不同SizeConst的子类型,但我仍然觉得很奇怪。

接下来我将需要创建一个警报类数组,这将再次让我陷入同样的​​麻烦。

1 个答案:

答案 0 :(得分:2)

使它成为一个结构数组,而不是一个类对象数组。

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

当我尝试时,Marshal.SizeOf()返回189.