/* https://stackoverflow.com/questions/7299097/dynamically-replace-the-contents-of-a-c-sharp-method
For .NET 4 and above "C:\Program Files (x86)\MSBuild\14.0\Bin\csc.exe" /unsafe+ /out:replacemethod.exe replacemethod.cs && start "replacemethod.exe" replacemethod.exe
PrintInfo: Version x64 Release 1. Replace Instance Method Class1.Demo()
Demo
Replace result: True
Foo 2. Replace Instance Overload of Method Class1.Demo(10)
Demo: 10
Replace result: True
Foo: 10 3. Replace Static Method Class1.DemoStatic()
DemoStatic
Replace result: True
FooStatic Press any key to EXIT...
*/ using System;
using System.Reflection;
using System.Runtime.CompilerServices; class Program {
public static void Main(params string[] args){
PrintInfo();
Console.WriteLine(); Test(); Console.Write("\nPress any key to EXIT...");
Console.ReadKey(true);
} public static void PrintInfo() {
Console.Write("PrintInfo: ");
if (IntPtr.Size == ) {
#if DEBUG
Console.WriteLine("Version x86 Debug");
#else
Console.WriteLine("Version x86 Release");
#endif
} else {
#if DEBUG
Console.WriteLine("Version x64 Debug");
#else
Console.WriteLine("Version x64 Release");
#endif
}
} public static void Test() {
Console.WriteLine("1. Replace Instance Method Class1.Demo()");
var o = new Class1();
o.Demo();
var r = CSharpUtils.ReplaceMethod(typeof(Class1), "Demo", typeof(Program), "Foo");
Console.WriteLine("Replace result: {0}", r);
o.Demo(); Console.WriteLine(); Console.WriteLine("2. Replace Instance Overload of Method Class1.Demo(10)");
o.Demo();
r = CSharpUtils.ReplaceMethod(typeof(Class1), "Demo", typeof(Program), "Foo", types:new Type[]{ typeof(int) });
Console.WriteLine("Replace result: {0}" ,r);
o.Demo(); Console.WriteLine(); Console.WriteLine("3. Replace Static Method Class1.DemoStatic()");
Class1.DemoStatic();
r = CSharpUtils.ReplaceMethod(typeof(Class1), "DemoStatic", typeof(Program), "FooStatic", BindingFlags.Static|BindingFlags.NonPublic|BindingFlags.Public);
Console.WriteLine("Replace result: {0}" ,r);
Class1.DemoStatic();
} private void Foo() {
Console.WriteLine("Foo");
} private void Foo(int d) {
Console.WriteLine("Foo: {0}", d);
} private static void FooStatic() {
Console.WriteLine("FooStatic");
}
} class Class1 {
public void Demo() {
Console.WriteLine("Demo");
} public void Demo(int d) {
Console.WriteLine("Demo: {0}", d);
} public static void DemoStatic() {
Console.WriteLine("DemoStatic");
}
} public static class CSharpUtils {
public static bool ReplaceMethod(Type targetType, string targetMethod, Type injectType, string injectMethod, BindingFlags bindingAttr = BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public, Binder binder = null, CallingConventions callConvention = CallingConventions.Any, Type[] types = null, ParameterModifier[] modifiers = null) {
if (types == null) {
types = Type.EmptyTypes;
}
MethodInfo tarMethod = targetType.GetMethod(targetMethod, bindingAttr, binder, callConvention, types, modifiers);
MethodInfo injMethod = injectType.GetMethod(injectMethod, bindingAttr, binder, callConvention, types, modifiers);
if (tarMethod == null || injMethod == null) {
return false;
}
RuntimeHelpers.PrepareMethod(tarMethod.MethodHandle);
RuntimeHelpers.PrepareMethod(injMethod.MethodHandle);
unsafe {
if (IntPtr.Size == ) {
int* tar = (int*)tarMethod.MethodHandle.Value.ToPointer() + ;
int* inj = (int*)injMethod.MethodHandle.Value.ToPointer() + ;
*tar = *inj;
} else {
long* tar = (long*)tarMethod.MethodHandle.Value.ToPointer() + ;
long* inj = (long*)injMethod.MethodHandle.Value.ToPointer() + ;
*tar = *inj;
}
}
return true;
}
}

C# 运行时替换方法(需要unsafe编译)的更多相关文章

  1. 1.2 - C#语言习惯 - 用运行时常量readonly而不是编译期常量const

    C#中有两种类型的常量:编译期常量和运行时常量.二者有着截然不同的行为,使用不当将会带来性能上或正确性上的问题. 这两个问题最好都不要发生,不过若难以同时避免的话,那么一个略微慢一些但能保证正确的程序 ...

  2. gohook 一个支持运行时替换 golang 函数的库实现

    运行时替换函数对 golang 这类静态语言来说并不是件容易的事情,语言层面的不支持导致只能从机器码层面做些奇怪 hack,往往艰难,但如能成功,那挣脱牢笼带来的成就感,想想就让人兴奋. gohook ...

  3. Objective-C运行时编程 - 方法混写 Method Swizzling

    摘要: 本文描述方法混写对实例.类.父类.不存在的方法等情况处理,属于Objective-C(oc)运行时(runtime)编程范围. 编程环境:Xcode 6.1.1, Yosemite,iOS 8 ...

  4. OC运行时和方法机制笔记

    在OC当中,属性是对字段的一种特殊封装手段. 在编译期,编译器会将对字段的访问替换为内存偏移量,实质是一种硬编码. 如果增加一个字段,那么对象的内存排布就会改变,需要重新编译才行. OC的做法是,把实 ...

  5. 趣谈iOS运行时的方法调用原理

    一个成熟的计算机语言必然有丰富的体系,复杂的容错机制,处理逻辑以及判断逻辑.但这些复杂的逻辑都是围绕一个主线丰富和展开的,所以在学习计算机语言的时候,先掌握核心,然后了解其原理,明白程序语言设计的实质 ...

  6. 《C#高效编程》读书笔记02-用运行时常量(readonly)而不是编译期常量(const)

    C#有两种类型的常量:编译期常量和运行时常量.两者有截然不同的行为,使用不当的话,会造成性能问题,如果没法确定,则使用慢点,但能保证正确的运行时常量. 运行时常量使用readonly关键字声明,编译期 ...

  7. MEF在运行时替换插件

    利用AppDomain的ShadowCopy特性. var setup = new AppDomainSetup { CachePath = cachePath, ShadowCopyFiles = ...

  8. c# 运行时替换某文件源代码(将XML 转换成 某个枚举并写入源文件)

    var sr = new StreamReader(Server.MapPath("~/WEB-INF/rule.config")); XmlDocument doc = new ...

  9. java 利用java运行时的方法得到当前屏幕截图的方法(转)

    将截屏图片保存到本地路径: package com.test; import java.awt.AWTException; import java.awt.Dimension; import java ...

随机推荐

  1. 使用electron进行原生应用的打包(2)---主进程与渲染进程之间的通信

    上一篇讲了使用electron进行打包的配置相关文件,这篇主要讲electron中很重要的通信方式. 首先解释一个概念: electron打包的应用包含两个部分 electron的环境(node),也 ...

  2. jmeter断言之BeanShell断言

    1.添加BeanShell断言,在Script下面写断言脚本,常用的BeanShell脚本如下: if(!SampleResult.getResponseCode().equals("200 ...

  3. 005-TCP传输控制协议

    一.概述 传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793定义.在简化的 ...

  4. tensorflow 的rnn的示例 ptb_word_lm.py 的完整代码

    其训练数据源在我的空间里,名字为:tensorflow的ptb-word-lm示例的训练数据源.tgz 讲解参见另一篇文章:  http://www.cnblogs.com/welhzh/p/6739 ...

  5. 利用WebBrowser实现自动登入功能

    公司内部改革,对考勤方面做出调整,要求实现办公自动化,在OA进行上下班考勤:作为程序员,突发奇想如何实现自动化考勤应用? 需求如下: 可设置考勤地址.用户信息.上下班时间: 根据设置的上下班时间,定时 ...

  6. 关于shared pool的深入探讨(四)

    我们进一步来讨论一下shared pool的处理: 先进行相应查询,获得测试数据: [oracle@jumper udump]$ sqlplus "/ as sysdba" SQL ...

  7. php strtotime 函数UNIX时间戳

    int strtotime ( string time [, int now]) 本函数预期接受一个包含英文日期格式的字符串并尝试将其解析为 UNIX 时间戳. 如果 time 的格式是绝对时间则 n ...

  8. mysql如果主库宕机,如何解决?

    两种情况服务器down机,数据库down机 如果此时需要切从库 1.先show processlist\G,查看状态 如果看到两个状态,说明此时的从库和主库是同步的 state: waiting fo ...

  9. curl简介、安装及使用

    目录 curl简介 curl安装 curl使用 curl简介 curl是Linux下一个强大的文件传输工具,它利用URL语法在命令行方式下工作,支持文件上传和下载. curl安装 Ubuntu系统键入 ...

  10. Linux Shell编程第1章——Shell脚本编程概述

    目录 Linux和Shell简介 Linux是一套可免费使用和自由传播的类UNIX操作系统.Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互操作的一种接口.它接收用户输入的命令,并把它送 ...