Tag: reflection.emit

克隆/复制将访问者主体添加到新类型

我正在从现有类型创建动态程序集中的新类型,但只包含选定的属性: public class EmitTest { public Type Create(Type prototype, Type dynamicBaseType, List includedPropertyList) { AssemblyName aName = new AssemblyName(“DynamicAssembly”); AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( aName, AssemblyBuilderAccess.RunAndSave); ModuleBuilder modulBuilder = assemblyBuilder.DefineDynamicModule(aName.Name, aName.Name + “.dll”); string typeName = string.Concat(prototype.Name, “_DynamicType_”, Guid.NewGuid().ToString().Replace(“-“, string.Empty)); TypeBuilder typeBuilder = modulBuilder.DefineType( typeName, TypeAttributes.Public, null, new Type[] { }); foreach (string s in includedPropertyList) […]

OpCodes.Castclass。 有必要吗?

当你准备调用带有类型参数的方法时,当你在堆栈顶部引用(B)的实例时,是否需要发出OpCode.CastClass(typeof(A)),其中B是类,派生自A一个? 加成: interface IFoo { void IFoo(); } public class A:IFoo { public void IFoo() { } } public class B:A,IFoo { new public void IFoo() { } } var b = new B(); (b as IFoo).Foo(); ((b as A) as IFoo).Foo();

reflection发射:如何为此构建构造函数

我想动态构建的代码如下: public class Sample { public Sample() { Items = new ObservableTestCollection(this); } public Sample(IEnumerable source) { Items = new ObservableTestCollection(this, source); } public ObservableTestCollection Items; } ObservableTestCollection的来源如下: public class ObservableTestCollection : ObservableCollection { public T Parent; public ObservableTestCollection(T parent) { Parent = parent; } public ObservableTestCollection(T parent, IEnumerable source) : base(source) { Parent = […]

Reflection.Emit:如何可靠地将MethodBuilder转换为RuntimeMethodInfo?

在动态生成类型并调用TypeBuilder.CreateType之后,我想创建一个指向新类型中的方法的委托。 但是,如果我使用像 loadedType = typeBuilder.CreateType(); myDelegate = (MyDelegate)Delegate.CreateDelegate( typeof(MyDelegate), methodBuilder); 将methodBuilder重用为methodInfo,我得到exception“MethodInfo必须是RuntimeMethodInfo”。 现在通常我可以重新获取MethodInfo MethodInfo mi = loadedType.GetMethod(methodBuilder.Name); myDelegate = (MyDelegate)Delegate.CreateDelegate(typeof(MyDelegate), mi); 但我的类可能包含几个具有相同名称的重载方法。 我怎样才能确保我找到合适的? 方法是否有一些我可以在loadedType中查找的持久标识符? 更新:好的,这是我用来重新获取MethodInfo的内容。 我只是希望我能确定它在所有情况下都有效。 private static MethodInfo ReacquireMethod(Type type, MethodInfo method) { BindingFlags flags = BindingFlags.DeclaredOnly; flags |= (method.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic); flags |= (method.IsStatic ? BindingFlags.Static : BindingFlags.Instance); MethodInfo m = type.GetMethod(method.Name, […]

从另一个AppDomain程序集复制方法并从CurrentDomain执行它

在大图中,我试图从主域中的dll执行方法,但之后,卸载该DLL。 到目前为止我已经创建了新的AppDomain加载了Assembly \ MaxStackSize ,使用MarshalByRefObject我将该方法的主体和MaxStackSize获取到主域,在那里创建DynamicMethod ,重新创建其中的主体并调用它。 但是当我调用它时,我得到exception: System.BadImageFormatException: Signature is not IMAGE_CEE_CS_CALLCONV_LOCAL_SIG 。 获取并调用它的代码: DynamicMethod method = new DynamicMethod( “func”, typeof( void ), new Type[ 0 ] ); var info = method.GetDynamicILInfo( ); info.SetCode( marshal.GetILCode( ), marshal.GetMaxStackSize()); info.SetLocalSignature( SignatureHelper.GetMethodSigHelper( CallingConventions.Standard, typeof( void ) ).GetSignature( ) ); method.Invoke( null, new object[ 0 ] ); //<– exception […]

为2Darrays生成IL

我想使用System.Reflection.Emit命名空间为2D数组构造生成IL。 我的C#代码是 Array 2dArr = Array.CreateInstance(typeof(int),100,100); 使用ildasm ,我意识到为上面的C#代码生成了以下IL代码。 IL_0006: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) IL_000b: ldc.i4.s 100 IL_000d: ldc.i4.s 100 IL_000f: call class [mscorlib]System.Array [mscorlib]System.Array::CreateInstance(class [mscorlib]System.Type, int32, int32) 我能够生成最后三个IL语句,如下所示。 MethodInfo createArray = typeof(Array).GetMethod(“CreateInstance”, new Type[] { typeof(Type),typeof(int),typeof(int) }); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Call, createArray); 但我不清楚如何生成拳头IL语句(即IL_0006: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle )) 你有什么主意吗? 此外,有人能指出一些关于如何使用System.Reflection.Emit命名空间以生成IL代码的好教程/文档吗?

Reflection.Emit.ILGeneratorexception处理“离开”指令

首先,一些背景信息: 我正在为一个学校项目编写一个编译器。 它已经在工作,我正在花费大量精力修复和/或优化它。 我最近遇到的一个问题是,当我调用以下任何成员方法时,我发现ILGenerator对象会生成一个额外的leave指令: BeginCatchBlock() BeginExceptFilterBlock() BeginFaultBlock() BeginFinallyBlock() EndExceptionBlock() 因此,您通过调用BeginExceptionBlock()启动try语句,使用BeginExceptionBlock()添加几个catch子句,可能使用BeginCatchBlock()添加finally子句,然后使用BeginFinallyBlock()结束受保护的代码区域。 我列出的方法会自动生成一条leave指令,该指令分支到try语句后的第一条指令。 出于两个原因,我不想要这些。 一,因为它总是生成一个leave.s优化的leave指令,而不是一个leave.s指令,即使它只是两个字节的分支。 第二,因为你无法控制离开指令的去向。 所以,如果你想分支到代码中的其他位置,你必须添加一个编译器生成的局部变量,根据你想要进入try语句的位置来设置它,让EndExceptionBlock()自动生成leave指令,然后在try块下面生成一个switch语句。 或者,您可以在调用之前的方法之前自己发出leave或leave.s指令,导致一个丑陋且无法访问的额外5个字节,如下所示: L_00ca: leave.s L_00e5 L_00cc: leave L_00d1 这两个选项对我来说都是不可接受的。 有没有办法阻止自动生成leave指令,或者是否有任何其他方式来指定受保护区域而不是使用这些方法(这些方法非常烦人且实际上没有记录)? 编辑注意:C#编译器本身就是这样做的,所以并不是说有充分的理由强迫它在我们身上。 例如,如果您有.NET 4.5 beta,请反汇编以下代码并检查它们的实现:(内部添加exception块) public static async Task TestAsync(int ms) { var local = ms / 1000; Console.WriteLine(“In async call, before await ” + local.ToString() + “-second delay.”); await System.Threading.Tasks.Task.Delay(ms); Console.WriteLine(“In […]

如何在C#/ IL中改变盒装值类型(原语或结构)

与如何使用IL改变盒装结构相关我试图以通用方式更改盒装值类型的值,因此尝试实现以下方法: void MutateValueType(object o, T v) where T : struct 所以以下应该是可能的: var oi = (object)17; MutateValueType(oi, 43); Console.WriteLine(oi); // 43 var od = (object)17.7d; MutateValueType(od, 42.3); Console.WriteLine(od); // 42.3 我没有得到它在.NET Framework上工作(请参阅@hvd的评论,没有typeof(Program).Module适用于其他运行时)。 我已经实现了这个,如下所示。 但是,在使用以下命令调用委托del时,这会失败: System.Security.VerificationException: ‘Operation could destabilize the runtime.’ 这是我提出的实现: public static void MutateValueType(object o, T v) { var dynMtd = new DynamicMethod(“EvilMutateValueType”, typeof(void), new […]

Reflection.Emit构建实体图

我花了一些时间尝试使用Reflection.Emit动态构建实体图。 使用新的平面类型(类)创建程序集,实例化它并使用reflection很容易并且工作正常。 但是当涉及到构建具有另一个动态类的generics列表的结构时,它变得更加复杂并且我被卡住了。 基本上,我想动态构建以下结构: public class Head { public string HeadId { get; set; } public AssignmentType HeadType { get; set; } public int TestIndicator { get; set; } public List Items { get; set; } public Head() { Items = new List(); } } public class Item { public string ItemId { get; set; […]

动态类型创建中的MethodBuilder.CreateMethodBody()问题

对于实验,我试图从源类型读取方法体(使用GetILAsByteArray() )并将其添加到新类型(使用CreateMethodBody() )。 我的源类就是这个 public class FullClass { public string Test(string data) { return data; } public string Test2(string data) { return data; } public string Test5(string data, string data1) { return data + data1; } } 为此代码生成的IL(使用reflection器拍摄) .method public hidebysig instance string Test(string data) cil managed { .maxstack 1 .locals init ( [0] string […]