0

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?

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
Giovani Luigi
  • 121
  • 1
  • 10
  • what platform are you using – adjan Dec 02 '17 at 22:01
  • The issue seems to be with `AnsiBStr`. `BStr`/`LPStr`/`LPWStr` seem fine https://stackoverflow.com/questions/6471421/marshal-c-char-in-c-sharp – Slai Dec 02 '17 at 22:25
  • I am compiling to AnyCPU in a x64 Windows. – Giovani Luigi Dec 03 '17 at 00:26
  • 1
    AnsiBStr just can't be stored in a class or structure member. It is *always* a variable-length array of 8-bit characters, the first byte in the array says how many characters follow. So neither SizeConst nor SizeParamIndex can apply. It is only usable on a function argument. Pretty doubtful that the declaration is close to what is needed, we can't see the native declaration, but you can hack it by declaring the length prefix as Byte and the rest as Char() with UnmanagedType.ByValTStr. – Hans Passant Dec 03 '17 at 15:12

2 Answers2

0

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:

TnTinMn
  • 11,522
  • 3
  • 18
  • 39
-1

im trying to help. Marshall is used for Value Types ex : struct. Class is Reference type which is no need to calculate unused object inside of it. U need to use ex:struct to make its works. I give an example of my code, but sorry I wrote it at C#

class Program
{
    static void Main(string[] args)
    {
        TestingData p = new TestingData();
        Console.WriteLine("Number of bytes : {0}", Marshal.SizeOf(p));
    }
}

public struct TestingData
{
    public string a;
}

Hope its gonna help. for more information you can go here Marshal Documentation

madqori
  • 37
  • 8