Search code examples
.netvb.netmarshallingunmanaged

Marshal.SizeOf() cannot calculate size of object containing string


Marshal.SizeOf() will throw an exception when trying to calculate the lenght of an object of type MyClass.

Here is the class:

<StructLayout(LayoutKind.Sequential, Pack:=1)>
Public Class MyClass

    Public ReadOnly UniqueId As Long

    <MarshalAs(UnmanagedType.AnsiBStr, SizeConst:=60, SizeParamIndex:=0)>
    Public ReadOnly Name As String

End Class

This code will fail:

Dim MyObject = New MyClass()
Dim size  = Marshal.SizeOf(MyObject) 'will throw exception here. Why?

It will throw the exception "no meaningful size or offset can be computed"

How can I get the lenght of MyObject instead?


Solution

  • I believe that UnmanagedType.AnsiBStr can only be used on parameters (passed values) of a method signature.

    A reference to a BSTR is a pointer to a length prefixed character array. As such it will be a .Net Intptr with a size of 4 or 8 bytes depending on process bitness (x32 or x64). If you need ANSI characters, you define that as part of the StructLayout declaration and tag the string as a UnmanagedType.BStr

    <StructLayout(LayoutKind.Sequential, Pack:=1, CharSet:=CharSet.Ansi)>
    Public Class [MyClass]
         Public ReadOnly UniqueId As Long
        <MarshalAs(UnmanagedType.BStr)>
         Public ReadOnly Name As String
    End Class
    

    Recommended reading: