CharSet enumeration for P/Invoke and StructLayout
Hongmeig blogs about the difference between Marshal.SizeOf(typeof(char)) and sizeof(char).
The reason for this is that a char in unmanaged code (P/Invoke, marshalling) is 1 byte and like Hongmeig says in the .NET framework a char is Unicode, so 2 bytes.
What I'd like to point out though, is that we do have control over the character set when using P/Invoke calls and the physical layout of structs with regards to the character set. This can be very useful for string marshalling.
It can be achieved by using the System.Runtime.InteropServices.CharSet enumeration {Ansi,Auto,None,Unicode}, which can be applied on the DllImportAttribute and the StructLayoutAttribute.
For instance:
using System;
using System.Runtime.InteropServices;
class Class1
{
static void Main(string[] args)
{
unsafe
{
Console.WriteLine("Marshal.SizeOf(typeof(TestAnsi) shows: " + Marshal.SizeOf(typeof(TestAnsi)));
Console.WriteLine("Marshal.SizeOf(typeof(TestUnicode) shows: " + Marshal.SizeOf(typeof(TestUnicode)));
}
}
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct TestAnsi
{
public char testbyte;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct TestUnicode
{
public char testbyte;
}
This results in the following output:
Marshal.SizeOf(typeof(TestAnsi) shows: 1
Marshal.SizeOf(typeof(TestUnicode) shows: 2
This CharSet enumeration can be applied in a similar fashion on the DllImportAttribute.