C
C#6d ago
Rosentti

Strange Marshalling issue

Hi, I'm hitting a strange issue. My Handle_t type, which simply contains an Int32 is the same length as an Int32, as expected. However when it's included in another struct and it's size is checked, the size is incorrect. See below code sample:
c#
using System;
using System.Text;
using System.Runtime.InteropServices;

public class Program
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Handle_t
{
public Int32 m_value;
}

[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct Test_t
{
public Handle_t Test;

[MarshalAs(UnmanagedType.I1)]
public bool Test2;

[MarshalAs(UnmanagedType.I1)]
public bool Test3;
}

[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct TestInt_t
{
public Int32 Test;

[MarshalAs(UnmanagedType.I1)]
public bool Test2;

[MarshalAs(UnmanagedType.I1)]
public bool Test3;
}

public static void Main()
{
Console.WriteLine(Marshal.SizeOf<Int32>()); // 4, OK
Console.WriteLine(Marshal.SizeOf<Handle_t>()); // 4, OK
Console.WriteLine(Marshal.SizeOf<Test_t>()); // 6, not OK, why? It should be 8, as Handle_t only contains an Int32, and is 4 bytes
Console.WriteLine(Marshal.SizeOf<TestInt_t>()); // 8, as expected.
}
}
c#
using System;
using System.Text;
using System.Runtime.InteropServices;

public class Program
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Handle_t
{
public Int32 m_value;
}

[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct Test_t
{
public Handle_t Test;

[MarshalAs(UnmanagedType.I1)]
public bool Test2;

[MarshalAs(UnmanagedType.I1)]
public bool Test3;
}

[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct TestInt_t
{
public Int32 Test;

[MarshalAs(UnmanagedType.I1)]
public bool Test2;

[MarshalAs(UnmanagedType.I1)]
public bool Test3;
}

public static void Main()
{
Console.WriteLine(Marshal.SizeOf<Int32>()); // 4, OK
Console.WriteLine(Marshal.SizeOf<Handle_t>()); // 4, OK
Console.WriteLine(Marshal.SizeOf<Test_t>()); // 6, not OK, why? It should be 8, as Handle_t only contains an Int32, and is 4 bytes
Console.WriteLine(Marshal.SizeOf<TestInt_t>()); // 8, as expected.
}
}
3 Replies
Rosentti
Rosentti6d ago
Welp, that was a quick fix that I didn't think of before. I just removed StructLayout from the Handle_t type altogether, and that fixed it. Now both of them are 8 bytes, as expected. I guess it layouted the internal fields of an Int32 too?
reflectronic
reflectronic6d ago
it's 6 because you said Handle_t is byte-aligned, not int-aligned, by writing Pack = 1 it means that the size of Test_t does not have to be a multiple of 4 4 + 1 + 1 is 6, and it does not need to round to satisfy the alignment, so it remains 6 once you got rid of that, then Handle_t is int-aligned, and the size is rounded up to the next multiple of 4
Rosentti
Rosentti6d ago
Ah. Makes sense actually. Thanks for the explanation!
Want results from more Discord servers?
Add your server