I have a problem with reflection in combination with MarshalAs attributes. I would like to dynamically create structs with reflection durng runtime. The structs may contain arrays which need to me marshaled. The Field.SetMarshal() Method is obsoletze since .NET 2.0 and I'm failing to find an alternative.
Example of struct which im building during runtime:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct Example
{
public int var1;
public float var2;
public byte var3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public int[] var4;
}
Code using reflection to build structs:
TypeBuilder tb = mb.DefineType(pT.name, // Name of struct type
TypeAttributes.Public | // Public scope
TypeAttributes.SequentialLayout | // Sequential layout
TypeAttributes.AnsiClass, // Ansi Charset
typeof(ValueType), // Value type
PackingSize.Size1); // Packing size is 1 byte
// Add public fields to new struct type
foreach (parsedField pF in pT.fields)
{
FieldBuilder fb = tb.DefineField(pF.name, pF.type, FieldAttributes.Public);
// Add Marshall information to arrays
if (fb.FieldType.IsArray)
{
// ADD MARSHAL INFORMATION HERE
}
}
In the documentation of the obsolete UnmanagedMarshal class Microsoft says: "Emit the MarshalAs custom attribute instead"
Well I tried to make an CustomAttribute ("MarshalAs") and added it with Field.SetCustomAttribute() but this does not work either - the size of the struct is alyways wrong.
[AttributeUsage(AttributeTargets.Field)]
public class MarshalAs : System.Attribute
{
public UnmanagedType type;
public int SizeConst;
public MarshalAs(UnmanagedType type, int SizeConst)
{
this.type = type;
this.SizeConst = SizeConst;
}
}
...
TypeBuilder tb = mb.DefineType(pT.name, // Name of struct type
TypeAttributes.Public | // Public scope
TypeAttributes.SequentialLayout | // Sequential layout
TypeAttributes.AnsiClass, // Ansi Charset
typeof(ValueType), // Value type
PackingSize.Size1); // Packing size is 1 byte
// Add public fields to new struct type
foreach (parsedField pF in pT.fields)
{
FieldBuilder fb = tb.DefineField(pF.name, pF.type, FieldAttributes.Public);
// Add Marshall information to arrays
if (fb.FieldType.IsArray)
{
ConstructorInfo ci = typeof(MarshalAs).GetConstructor(new Type[] { typeof(UnmanagedType), typeof(int) });
CustomAttributeBuilder customBuilder = new CustomAttributeBuilder(ci, new object[] { UnmanagedType.ByValArray, 8 });
fb.SetCustomAttribute(customBuilder);
}
}
Does anyone have an idea what I can do?
best regards
Aucun commentaire:
Enregistrer un commentaire