2012-03-19 27 views
9

Câu hỏi: chương trình sau in ra sao?StructLayout Pack = 1 không hoạt động với bool?

using System; 
using System.Runtime.InteropServices; 

namespace ConsoleApplication2 { 

    [StructLayout(LayoutKind.Sequential, Pack=1)] 
    struct Struct1 { 
     bool b; 
     int i; 
    } 

    [StructLayout(LayoutKind.Sequential, Pack=1)] 
    struct Struct2 { 
     byte b; 
     int i; 
    } 

    class Program { 
     static void Main(string[] args) { 
      Console.WriteLine(Marshal.SizeOf(typeof(Struct1))); 
      Console.WriteLine(Marshal.SizeOf(typeof(Struct2))); 
      Console.ReadKey();    
     } 
    } 
} 

Trả lời:

8 
5 

Đây là rất khó hiểu đối với tôi. Cả bool và byte đều có kích thước 1 byte và chỉ định [StructLayout(LayoutKind.Sequential, Pack=1)] nên vô hiệu hóa mọi vấn đề về đệm. Cả hai cấu trúc phải là 5 byte. Vì vậy, tôi có hai câu hỏi:

  • Tại sao marshalling hoạt động theo cách này?
  • Bất kỳ giải pháp nào khác? Tôi có booleans 1-byte trong cấu trúc bản địa tôi cần phải nhập. Tôi có thể sử dụng byte thay vì tất nhiên nhưng nó "lộn xộn".

Cảm ơn.

Trả lời

18

Theo mặc định, loại .NET bool so khớp với loại không được quản lý BOOL, là typedef được chỉnh sửa thành int. Nếu bạn muốn sắp xếp đến và đi từ 1 byte dữ liệu boolean không được quản lý, cho biết điều này để các marshaler với một thuộc tính:

[StructLayout (LayoutKind.Sequential, Pack=1)] 
struct Struct3 { 
    [MarshalAs (UnmanagedType.I1)] 
    bool b; 
    int i; 
} 

Console.WriteLine (Marshal.SizeOf (typeof (Struct3))) ; // prints 5 
+0

Đó là một Microsoft-ism: bool là 1 byte trong C và C++. Nó sẽ không bao giờ xảy ra với tôi rằng họ sẽ soái với một typedef cụ thể của Microsoft. – Asik

+9

booleans chỉ là số nguyên trong C (ít nhất là trước C99). Chỉ C++ có một kiểu 'bool' riêng. Đối với khả năng tương tác sử dụng 'int' như boolean là tốt hơn, vì nó phổ biến hơn. – SztupY

2

bool được marshalled đến một int32, vì lý do khả năng tương tác (C++ chương trình C/thường sử dụng int như boolean và trong winapi BOOLtypedef cũng được chỉnh sửa thành int), do đó, nó được chuyển đổi thành 4 byte.

Các vấn đề liên quan