Reflect on Marshal Attributes?

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;
}
 
N

Nicholas Paldino [.NET/C# MVP]

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.
 
W

William Stacey

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;
}
 
M

Mattias Sjögren

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top