2013-03-24 90 views
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類。

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. 
+1

爲什麼你要手動編組,而不是依靠運行時來做本地方法調用? – alex 2013-03-24 10:54:45

+0

我對C#相當陌生 - 請問你能否提出你的建議 – lolonapoli 2013-03-24 11:56:18

回答

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

+2

請注意有些網站的'camelCase'私有方法。 – 2013-03-24 11:10:30

+0

@MatthewWatson不一致性很大?我堅持我的觀點,認爲「PascalCase」是一種很好的習慣,只是爲了保持一致性。 – antonijn 2013-03-24 11:44:28