封送一个对象数组

本文关键字:数组 一个对象 | 更新日期: 2023-09-27 18:05:49

我有以下程序:

[StructLayout(LayoutKind.Sequential)]
class SwitchTime
{
    public byte st1 { get; set; }
    public byte st2 { get; set; }
}
[StructLayout(LayoutKind.Sequential,Size=3)]
class SwitchParam
{
    public byte sp1 { get; set; }
    public byte sp2 { get; set; }
    public byte sp3 { get; set; }
}
[StructLayout(LayoutKind.Sequential)]
class SwitchRecord
{
    public SwitchTime switchTime;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
    public SwitchParam[] switchParams;
}

我有:

void populate( SwitchRecord SR)
{
    SR.switchTime = new SwitchTime();
    SR.switchTime.st1 = 1;
    SR.switchTime.st2 = 2;
    SR.switchParams = new SwitchParam[2];
    SR.switchParams[0] = new SwitchParam();
    SR.switchParams[0].sp1 = 3;
    SR.switchParams[0].sp2 = 4;
    SR.switchParams[0].sp3 = 5;
    SR.switchParams[1] = new SwitchParam();
    SR.switchParams[1].sp1 = 6;
    SR.switchParams[1].sp2 = 7;
    SR.switchParams[1].sp3 = 8;
}
byte[] StructureToByteArray(object obj)
{
    int len = Marshal.SizeOf(obj);//Exception here
    byte[] arr = new byte[len];
    IntPtr ptr = Marshal.AllocHGlobal(len);
    Marshal.StructureToPtr(obj, ptr, true);
    Marshal.Copy(ptr, arr, 0, len);
    Marshal.FreeHGlobal(ptr);
    return arr;
}
public MainWindow()
{
    InitializeComponent();
    SwitchRecord SR = new SwitchRecord();
    populate(SR);
    byte[] b = StructureToByteArray(SR.switchTime);     //Works!
    b = StructureToByteArray(SR.switchParams[0]);       //Works!
    try
    {
        b = StructureToByteArray(SR.switchParams);      //Failed!
    }
    catch (Exception err)
    {
        Console.WriteLine(err.Message);
    }
}

运行时程序无法封送嵌套在SwitchRecord类中的SwitchParams数组。

StructureToByteArray函数中int len = Marshal.SizeOf(obj);处出现以下错误:

Type 'WpfApplication2.MainWindow+SwitchParam[]' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.

封送一个对象数组

StrucyLayoutAttribute在它的名字中说,它应该应用于结构体,而不是类,所以你应该有:

[StructLayout(LayoutKind.Sequential)]
struct SwitchTime
{
    public byte st1 { get; set; }
    public byte st2 { get; set; }
}
[StructLayout(LayoutKind.Sequential,Size=3)]
struct SwitchParam
{
    public byte sp1 { get; set; }
    public byte sp2 { get; set; }
    public byte sp3 { get; set; }
}
[StructLayout(LayoutKind.Sequential)]
struct SwitchRecord
{
    public SwitchTime switchTime;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
    public SwitchParam[] switchParams;
}

作为旁注,在将来PascalCase你的方法,不要camelCase他们。c#中的方法在遵循约定时总是PascalCased