ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 如何使用来自同一程序集的静态变量的动态方法?

2019-06-26 01:52:29  阅读:280  来源: 互联网

标签:c net reflection cil mono-cecil


我创建了一个动态方法,但是当我尝试访问外部资源时,它给了我一个例外

TargetInvocationException: Exception has been thrown by the target of
an invocation.

基本上我想写一个字节数组的方法,然后将其作为动态方法加载.我知道一个简单的字节数组不足以重建元数据链接,但是如何使用来自同一程序集的变量的动态方法呢?

我试图转换该代码:

public static int z = 10;
public static int sum(int x, int y) {
    return x + y + z;
}

这给了我IL:

0        L_0000:      ldarg.0      
1        L_0001:      ldarg.1      
2        L_0002:      add          
3        L_0003:      ldsfld       System.Int32 CodeGen.Program::z
4        L_0008:      add          
5        L_0009:      ret  

哪个是字节:

02 03 58 7E 06 00 00 04 58 2A

我测试了它:

public static int z = 10;

static void Main(string[] args) {

    DynamicMethod sum = new DynamicMethod("sum", typeof(int), new Type[] { typeof(int), typeof(int) });
    var info = sum.GetDynamicILInfo();
    var bytes = new byte[] { 0x02, 0x03, 0x58, 0x7E, 0x06, 0x00, 0x00, 0x04, 0x58, 0x2A }; // { 0x02, 0x17, 0x58, 0x2A }; // this is a code for int sum(int x, int y) { return x + y; }

    info.SetCode(bytes, 8);

    var sig = SignatureHelper.GetMethodSigHelper(CallingConventions.Standard, typeof(int));
    byte[] bsig = sig.GetSignature();
    bsig[0] = 0x7;

    info.SetLocalSignature(bsig);

    int x = (int) sum.Invoke(null, new object[] { 10, 20 });
    Console.WriteLine(x.ToString());
    Console.ReadLine();
}

TL; DR我想修复表示动态方法IL的字节数组的引用.怎么做?另外,我不想使用ILGenerator(),我想要一个字节数组.

解决方法:

元数据令牌不能按原样重用;相反,你需要使用DynamicILInfo.GetTokenFor来获得一个与你可以使用的字段相对应的新标记.在你的情况下,这看起来像这样:

var tok = info.GetTokenFor(typeof(...).GetField("z").FieldHandle);
bytes[4] = tok;    
bytes[5] = tok >> 8;
bytes[6] = tok >> 16;
bytes[7] = tok >> 24;

但是,您可能还需要创建DynamicMethod,以便禁用JIT可见性检查,或者无论如何您的方法都无法访问私有字段.

在一个不相关的说明中,我不清楚你在使用签名信息做什么 – 看起来你出于某种原因将局部变量签名设置为修改后的方法签名…我认为你应该做更多的事情改为:

info.SetLocalSignature(SignatureHelper.GetLocalVarSigHelper().GetSignature())

当然,您需要根据您的方法实际使用的本地人来改变这一点.

标签:c,net,reflection,cil,mono-cecil
来源: https://codeday.me/bug/20190626/1288943.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有