Type Summary

Type Summary

public sealed class StructLayoutAttribute : Attribute


    // Constructors

       public StructLayoutAttribute(LayoutKind layoutKind);

    CF public StructLayoutAttribute(short layoutKind);

    // Fields

    CF public CharSet CharSet;

    CF public int Pack;

       public int Size;

    // Properties

    CF public LayoutKind Value { get; }


JM You will notice that this attribute has two constructors. One takes a LayoutKind and the other takes a short. You can see a possible design problem here, right? The one that takes the enum restricts (from a developer's point of view) the layout to the fields defined in LayoutKind. A short can be any short value inside or outside the range of LayoutKind. This can be error-prone. The designers said it was created to make it easier for type library importers to emit Interop assemblies, but even the designers said they dislike the overload.

AN A few people have wondered why several of the custom attributes in System.Runtime.InteropServices have two constructors—one that takes an enumeration and one that takes a short. This is not a recommended design practice; it was done for legacy reasons to make it easier for the type library importer to emit these attributes.

BG I found out something a little arcane about declaring PInvoke methods that might save users some amount of time.

If you have a method that takes a native struct, you have two options for declaring that struct. You can make it a value class ("struct" in C#), or a normal class. This choice doesn't seem very interesting, but your function prototype must use different syntax depending on your choice. For example, if your native method is prototyped as such:

bool GetVersionEx(OSVERSIONINFO & lposvi);

you must use one of the two following sets of syntax:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]

internal struct OSVERSIONINFO {  ...  }

[DllImport("KERNEL32", CharSet=CharSet.Auto)]

internal static extern bool GetVersionEx(ref OSVERSIONINFO lposvi);


[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] internal class OSVERSIONINFO { ... } [DllImport("KERNEL32", CharSet=CharSet.Auto)] internal static extern bool GetVersionEx([In, Out] OSVERSIONINFO lposvi);

Note that classes require being marked as [In, Out] while value classes must be passed as ref parameters.

     Python   SQL   Java   php   Perl 
     game development   web development   internet   *nix   graphics   hardware 
     telecommunications   C++ 
     Flash   Active Directory   Windows