C#如何通过Reflection设置StructLayoutAttribute.Pack?

我通过reflection动态创建一个C#结构,当我在调试器中检查struct的Type时,我注意到StructLayoutAttribute.Pack默认为8.我想将Pack设置为1。

基本上,我想通过reflection来做可以通过将此属性添加到结构的声明来完成的操作:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] 

我在创建类型后尝试使用reflection,但由于StructLayoutAttribute属性没有Setter,因此会抛出exception。

我的预感是它需要在ModuleBuilder.DefineType(我当前正在设置LayoutKind等)的调用中发生,但我没有看到任何明显的相应TypeAttribute 。

任何指针赞赏。 这里有完整的课程代码:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.Reflection.Emit; namespace AcmeCo.Serializable { public class DynamicSimStructBuilder { private static Type structType; public static object GetStructInstance() { object ptInstance = Activator.CreateInstance(GetStruct(), new object[] { }); return ptInstance; } public static Type GetStruct() { if (structType != null) { return structType; } AppDomain myDomain = AppDomain.CurrentDomain; AssemblyName myAsmName = new AssemblyName("MyDynamicAssembly"); AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.RunAndSave); ModuleBuilder structModule = myAsmBuilder.DefineDynamicModule("StructModule", "MyDynamicAssembly.dll"); TypeBuilder structTypeBld = structModule.DefineType("AcmeCo.ThirdPartyAPIWrapper.DyanmicStruct", TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.SequentialLayout | TypeAttributes.Serializable | TypeAttributes.AnsiClass, typeof(ValueType)); // use a set of variables defined in an XML file to create Fields on the struct ThirdPartyAPIVariableCollection collection = ThirdPartyAPIVariableCollection.Deserialize(); foreach (ThirdPartyAPIVariable variable in collection.ThirdPartyAPIVariables) { FieldBuilder field = structTypeBld.DefineField(variable.Name, Type.GetType(variable.SystemDataType, true) , FieldAttributes.Public); } // Base class and base class constructor. Type objType = Type.GetType("System.Object"); ConstructorInfo objCtor = objType.GetConstructor(new Type[] { }); Type[] ctorParams = { }; ConstructorBuilder pointCtor = structTypeBld.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ctorParams); ILGenerator ctorIL = pointCtor.GetILGenerator(); // Build the constructor. Begin by invoking the base class // constructor. The zero-index parameter of the constructor // is the new instance. Store the values of the fields. ctorIL.Emit(OpCodes.Ldarg_0); ctorIL.Emit(OpCodes.Call, objCtor); ctorIL.Emit(OpCodes.Ret); // Create the type, and then create an instance of the type // (or not, doesn't hurt to comment the CreateInstance line out...) Type ptType = structTypeBld.CreateType(); object ptInstance = Activator.CreateInstance(ptType, new object[] { }); DynamicSimStructBuilder.structType = ptType; int sizeOfNewData = System.Runtime.InteropServices.Marshal.SizeOf(ptType); Console.WriteLine("New type is: " + sizeOfNewData); // save the newly created type to a DLL for use later // (or not, doesn't hurt to comment the next line out...) myAsmBuilder.Save("MyDynamicAssembly.dll"); return ptType; } } } 

看起来添加一个参数可以指定包装尺寸:

来自http://msdn.microsoft.com/en-us/library/eyzw8bhy.aspx :

 public TypeBuilder DefineType( string name, TypeAttributes attr, Type parent, PackingSize packsize )