简体   繁体   中英

StructLayout Pack=1 doesn't work with bool?

Quiz: what does the following program print?

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

Answer:

8
5

This is very confusing to me. Both bool and byte have a size of 1 byte, and specifying [StructLayout(LayoutKind.Sequential, Pack=1)] should nullify any padding issues. Both structs should be 5 bytes. So I have two questions:

  • Why does marshalling work this way?
  • Any workaround? I have 1-byte booleans in native structs I need to import. I can use byte instead of course but it's "messy".

Thanks.

By default, .NET type bool marshals to unmanaged type BOOL , which is typedef ed to int . If you want to marshal to and from 1-byte unmanaged booleans, indicate this to the marshaler with an attribute:

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

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

bool被铠到int32 ,互操作性的原因(C / C ++程序通常使用int为布尔值和在WINAPI BOOLtypedef ED作为int为好),因此它转换为4个字节。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM