Benutzer mit den meisten Antworten
Reflection und Marshaling

Frage
-
Hallo,
ich möchte zur Laufzeit ein struct erzeugen, wobei die Arrays des structs das MarshalAs Attribute aufweisen müssen:
Beispiel für ein zur Laufzeit erzeugtes struct:
[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; }
Das Erzeugen des structs scheint weitestgehend zu funktionieren jedoch weiß ich nicht wie ich die Marshaling Information des Arrays erzeugen soll (zumal die FieldBuilder.SetMarshal() Funktion veraltet ist).
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) { MarshalAsAttribute maa = new MarshalAsAttribute(UnmanagedType.ByValArray); maa.SizeConst = pF.arrSize; // ADD MARSHALING INFO HERE //fb.SetMarshal(?????); } }
besten Dank!
- Bearbeitet ReflectionDude Mittwoch, 22. Juli 2015 08:59 Formatierung
Antworten
-
Hallo,
vielen Dank für deine Antwort. Ich habe es nun folgendermaßen gelöst:
FieldBuilder fb = tb.DefineField(pF.name, pF.type, FieldAttributes.Public); // Add Marshall information to arrays // The "MarshallAs" attribute has to be passed with a CustomAttributeBuilder if (fb.FieldType.IsArray) { // First we define a list of types of the arguments of the "MarshalAs" attribute constructor Type[] argTypes = new Type[] { typeof(UnmanagedType) }; // Now we create a list of concrete constructor arguments for the "MarshalAs" attribute constructor object[] args = new object[] { UnmanagedType.ByValArray }; // We need the field information of "SizeConst" of the MarshalAs attribute FieldInfo[] sizeConstField = new FieldInfo[] { typeof(MarshalAsAttribute).GetField("SizeConst") }; // We create the value for the field "SizeConst" object[] sizeConstValue = new object[] { pF.arrSize }; // Now we retrieve the constructor of "MarshalAs" attribute that matches specified constructor argument types ConstructorInfo ci = typeof(MarshalAsAttribute).GetConstructor(argTypes); // Create builder for "MarshalAs" attribute CustomAttributeBuilder customBuilder = new CustomAttributeBuilder(ci, args, sizeConstField, sizeConstValue); // Set builder for MarshalAs attribute fb.SetCustomAttribute(customBuilder); }
- Als Antwort vorgeschlagen Arne Diekmann Mittwoch, 22. Juli 2015 14:32
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 24. Juli 2015 08:37
Alle Antworten
-
Hallo ReflectionDude,
versuch doch mal Folgendes:
// 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) { MarshalAsAttribute maa = new MarshalAsAttribute(UnmanagedType.ByValArray); maa.SizeConst = pF.arrSize; var attributeParams = new[] { typeof(UnmanagedType) }; var classCtorInfo = typeof(MarshalAsAttribute).GetConstructor(attributeParams); var attributeBuilder = new CustomAttributeBuilder(classCtorInfo, new object[] { UnmanagedType.ByValArray }); fb.SetCustomAttribute(attributeBuilder); } }
- Bearbeitet Arne Diekmann Mittwoch, 22. Juli 2015 12:40
-
Hallo,
vielen Dank für deine Antwort. Ich habe es nun folgendermaßen gelöst:
FieldBuilder fb = tb.DefineField(pF.name, pF.type, FieldAttributes.Public); // Add Marshall information to arrays // The "MarshallAs" attribute has to be passed with a CustomAttributeBuilder if (fb.FieldType.IsArray) { // First we define a list of types of the arguments of the "MarshalAs" attribute constructor Type[] argTypes = new Type[] { typeof(UnmanagedType) }; // Now we create a list of concrete constructor arguments for the "MarshalAs" attribute constructor object[] args = new object[] { UnmanagedType.ByValArray }; // We need the field information of "SizeConst" of the MarshalAs attribute FieldInfo[] sizeConstField = new FieldInfo[] { typeof(MarshalAsAttribute).GetField("SizeConst") }; // We create the value for the field "SizeConst" object[] sizeConstValue = new object[] { pF.arrSize }; // Now we retrieve the constructor of "MarshalAs" attribute that matches specified constructor argument types ConstructorInfo ci = typeof(MarshalAsAttribute).GetConstructor(argTypes); // Create builder for "MarshalAs" attribute CustomAttributeBuilder customBuilder = new CustomAttributeBuilder(ci, args, sizeConstField, sizeConstValue); // Set builder for MarshalAs attribute fb.SetCustomAttribute(customBuilder); }
- Als Antwort vorgeschlagen Arne Diekmann Mittwoch, 22. Juli 2015 14:32
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 24. Juli 2015 08:37