none
LPStruct valid on fields? RRS feed

  • Question

  • When, if ever, is it valid to place [MarshalAs(UnmanagedType.LPStruct)] on a field of a struct?  I can compile successfully using that attribute and setting on a struct's field, but when I try to use it, it always fails:

      int size = Marshal.SizeOf(typeof(MyStruct));

    Running that gets this error:

    Type 'MyStruct' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.


    -Brent Arias
    Saturday, June 20, 2009 2:56 AM

Answers

  • It has a bit of an unfortunate name, the only type you are able to use this on is a Guid, see this blog post on the subject for the details.
    Saturday, June 20, 2009 8:59 AM
  • Actually, that blogger is mistaken.  I've seen [MarshalAs(UnmanagedType.LPStruct)] used on plenty of types other than a Guid type (Reflector is handy!).  But the only location I've seen it used, is on an actual parameter list.  In other words, it decorates parameters of a function call (and usually they are not GUIDs). 

    But the attribute type, by its own declaration, implies it can be used on fields as well.  I've not seen it in practice, and I can't make that work (not even on a GUID!).

    There's hardly anyone who knows the inner details of the interop marshaler as well as Adam Nathan. After all, he worked on the team that implemented it back in the days, and wrote THE reference book on the topic.

    I'm sure you've seen LPStruct used all over, but I bet almost all of them where unneccesary. You'd be surprised by the number of declarations I've seen where it was available for no reason. It's unfortunate that the name is so misleading.

    Since the same attribute (MarshalAsAttribute) is used both on parameters and fields, there's no easy way for the C# compiler (without extra work) to help you verify that you don't use a UnmanagedType option where it doesn't make sense. Good thing the runtime verifier calls out the error.

    Mattias, C# MVP
    Tuesday, June 30, 2009 2:36 PM
    Moderator

All replies

  • It has a bit of an unfortunate name, the only type you are able to use this on is a Guid, see this blog post on the subject for the details.
    Saturday, June 20, 2009 8:59 AM
  • Actually, that blogger is mistaken.  I've seen [MarshalAs(UnmanagedType.LPStruct)] used on plenty of types other than a Guid type (Reflector is handy!).  But the only location I've seen it used, is on an actual parameter list.  In other words, it decorates parameters of a function call (and usually they are not GUIDs). 

    But the attribute type, by its own declaration, implies it can be used on fields as well.  I've not seen it in practice, and I can't make that work (not even on a GUID!).
    • Edited by Brent Arias Monday, June 29, 2009 8:47 PM more clarification
    Monday, June 29, 2009 8:45 PM
  • It is clearly documented in the MSDN article:

    Valid for platform invoke methods only.


    Hans Passant.
    Monday, June 29, 2009 10:27 PM
    Moderator
  • Actually, that blogger is mistaken.  I've seen [MarshalAs(UnmanagedType.LPStruct)] used on plenty of types other than a Guid type (Reflector is handy!).  But the only location I've seen it used, is on an actual parameter list.  In other words, it decorates parameters of a function call (and usually they are not GUIDs). 

    But the attribute type, by its own declaration, implies it can be used on fields as well.  I've not seen it in practice, and I can't make that work (not even on a GUID!).

    There's hardly anyone who knows the inner details of the interop marshaler as well as Adam Nathan. After all, he worked on the team that implemented it back in the days, and wrote THE reference book on the topic.

    I'm sure you've seen LPStruct used all over, but I bet almost all of them where unneccesary. You'd be surprised by the number of declarations I've seen where it was available for no reason. It's unfortunate that the name is so misleading.

    Since the same attribute (MarshalAsAttribute) is used both on parameters and fields, there's no easy way for the C# compiler (without extra work) to help you verify that you don't use a UnmanagedType option where it doesn't make sense. Good thing the runtime verifier calls out the error.

    Mattias, C# MVP
    Tuesday, June 30, 2009 2:36 PM
    Moderator