1

我有以下程序:

[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.
4

1 回答 1

1

以它的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遵循约定。

于 2013-03-24T10:56:45.053 回答