Reflect on Marshal Attributes?

  • Thread starter Thread starter William Stacey
  • Start date Start date
W

William Stacey

Using the following struct def, how can I tell (using reflection) if "ba"
has the marshal attribute and get the "ByValArray" and maybe even the size?
In the bigger picture, given a struct (or a class), how to decide if
"sizeof(MyStruct)" would fail before calling sizeof and having to use
Marshal.sizeof? TIA

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=1)]
public struct MyStruct
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=20)]
public byte[] ba;
}
 
William,

You are aware that sizeof and the static SizeOf method on the Marshal
class do two different things, right? The sizeof operator will tell you how
many bytes the value type takes up in the managed realm. The static SizeOf
method tells you the size in bytes in the unmanaged realm. This can produce
different results.

To get the attributes, you can call the GetCustomAttributes method on
the Type (or field, or method) instance that represents the structure (or
field, or method). You can pass in the type of MarshalAsAttribute to have
the method filter out on just those attributes.

Once you have that, you can cast the return value to an instance of
MarshalAsAttribute and then access the properties of the attribute. The
Value property represents the value from the UnmanagedType enumeration,
while the SizeConst property represents the SizeConst part of the attribute
declaration.

Hope this helps.
 
Thanks Nicholas. Good info, but this does not seem to work for me. You see
what is wrong? Cheers!

[StructLayout(LayoutKind.Sequential)]
public struct StructWithByteArray
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=20)]
public byte[] ba;
}

private void GetAttributes()
{
Console.WriteLine("GetAttributes:");
Type t = typeof(StructWithByteArray);
FieldInfo[] myFieldInfo;
myFieldInfo = t.GetFields(BindingFlags.NonPublic | BindingFlags.Instance |
BindingFlags.Public);
foreach(FieldInfo fi in myFieldInfo)
{
Object[] myAttributes = fi.GetCustomAttributes(true);
if(myAttributes.Length > 0)
{
Console.WriteLine("\nThe attributes for the member {0} are: \n", fi);
for(int j = 0; j < myAttributes.Length; j++)
Console.WriteLine("The type of the attribute is {0}.", myAttributes[j]);
}
}
}

--
William Stacey, MVP

Nicholas Paldino said:
William,

You are aware that sizeof and the static SizeOf method on the Marshal
class do two different things, right? The sizeof operator will tell you how
many bytes the value type takes up in the managed realm. The static SizeOf
method tells you the size in bytes in the unmanaged realm. This can produce
different results.

To get the attributes, you can call the GetCustomAttributes method on
the Type (or field, or method) instance that represents the structure (or
field, or method). You can pass in the type of MarshalAsAttribute to have
the method filter out on just those attributes.

Once you have that, you can cast the return value to an instance of
MarshalAsAttribute and then access the properties of the attribute. The
Value property represents the value from the UnmanagedType enumeration,
while the SizeConst property represents the SizeConst part of the attribute
declaration.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

William Stacey said:
Using the following struct def, how can I tell (using reflection) if "ba"
has the marshal attribute and get the "ByValArray" and maybe even the size?
In the bigger picture, given a struct (or a class), how to decide if
"sizeof(MyStruct)" would fail before calling sizeof and having to use
Marshal.sizeof? TIA

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=1)]
public struct MyStruct
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=20)]
public byte[] ba;
}
 
William,
Using the following struct def, how can I tell (using reflection) if "ba"
has the marshal attribute and get the "ByValArray" and maybe even the size?
In the bigger picture, given a struct (or a class), how to decide if
"sizeof(MyStruct)" would fail before calling sizeof and having to use
Marshal.sizeof?

MarshalAs is one of the pseudo custom attributes that don't get stored
as regular custom attributes in metadata, but instead has special
metadata representation. In v1.x, GetCustomAttributes doesn't return
this information, and the only way to get the marshal info is through
the unmanaged metadata COM API. In Whidbey, GetCustomAttributes should
return these attributes as well.



Mattias
 
Back
Top