元帅一组物体

时间:2013-03-24 10:50:51

标签: c# arrays marshalling

我有以下程序:

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

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

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

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

1 个答案:

答案 0 :(得分:0)

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