Quirks in .NET – Part 2 Marshalling Booleans

25 02 2010

.NET Quirks

February 25th | 2010

Quirks in .NET Part -2  Marshalling Booleans

In Quirks in .NET – Part 1, we talked about the quirky call vs. callvirt instructions.

This week Platform Invoke is under my microscope. It isn’t necessarily a quirk, but it can be a hair-pulling experience when you get it wrong. More specifically, getting the marshaling done properly. Even more challenging, getting it right on both 32-bit and 64-bit environments.

Marshaling Booleans

Marshaling is done primarily for two reasons: you need functionality that is not built into the .NET Framework, but is found in existing Win32 APIs; and you have existing functionality in an unmanaged library you want to reuse.

Let’s start with the basics: What managed types map to unmanaged types? Some are common sense and some are not. Let’s talk about the System.Boolean type for a second.

Most people assume it takes exactly 1 bit in managed world, but in memory it’s a byte. We can prove it with this code:

int sizeBoolean = sizeof (bool);
int sizeInt = sizeof (int);
Console.Out.WriteLine("size of boolean = {0}", sizeBoolean);
Console.Out.WriteLine("size of int = {0}", sizeInt);

The size of operator returns the value in bytes, and a bool is 1. Here’s where things get tricky. In unmanaged world, there are two types—three really—BOOL, BOOLEAN, and COM’s VARIANT_BOOL.

The .NET Framework will try guess which one you mean when marshaling, but it won’t always get it right. When a managed bool is marshaled in a Platform Invoke method, it will marshal it automatically as a 4 byte type which is the more common marshaling case. However, if you cause an interface to get marshaled to COM and that interface has a Boolean as a return or method parameter, it will marshal it automatically as a 2-byte VARIANT_BOOL. Since COM interfaces tend to mix and match Booleans of different sizes, it’s always best to be explicit about which Boolean to marshal it to using the MarshalAsAttribute attribute.

You’ll have to look at the IDL or header file of the unmanaged code to determine which you need to use. Sometimes it requires a bit of playing around too.

Unmanaged Type Size (in bytes) MarshalAs Enum
BOOL (Win32) 4 UnmanagedType.Bool
BOOLEAN (Win32) 1 UnmanagedType.I1
VARIANT_BOOL (COM) 2 UnmanagedType.VariantBool

In Quirks in .NET – Part 3 we’ll look at numbers and binary

Kevin Jones is a Team Lead at Thycotic Software, an agile software services and product development company based in Washington DC. Secret Server is our flagship password management software product. On Twitter? Follow Kevin


Actions

Information

3 responses

26 02 2010
http://tipsforcdevelopers.blogspot.com/

Nice information. I am curious for part 3, because I am working on a project which uses an unmanaged C Library, so all the quirks information about Marshaling is more then welcome;)

26 02 2010
Kevin J.

Glad you found it useful. Part 3 will cover marshalings strings, which can be very tricky :-) .

11 03 2010
Quirks in .NET - Part 3 | Thycotic Software Ltd. | Team Blog

[...] Quirks in .NET – Part 2, we looked at marshaling Booleans to Win32 and COM. Now, let’s talk about numbers and [...]

Leave a comment