我试图弄清楚为什么其中一位代表的工作方式不同。我基本上有这样的代表:
private delegate void _SetSomething(bool value);
private delegate Something _Find(string value);
private delegate T _AddSomething<T>();
对于每一个我必须知道他们指出的内存地址,所以我使用GetFunctionPointer并且我有三个地址,现在没什么特别的,除了我必须在内存中修补这些地址的事实,所以我查了一下他们在反汇编视图中看到了前两种方法的预期行为但不是最后一种:
var obj = new SomethingObj();
obj.SetSomething(true); // E8 XX XX XX XX calling exactly the first address got from the delegate
firstDel.DynamicInvoke(true); // starts calling from the fp value
var ret1 = obj.Find("something"); // E8 XX XX XX XX calling exactly the second address from the delegate
var ret2 = secondDel.DynamicInvoke("something"); // starts calling from the fp value
var ret3 = obj.AddSomething<SomeStuff>(); // E8 XX XX XX XX !!! Here the address does not match with the function pointer got from delegate
var ret4 = thirdDel.DynamicInvoke(null); // starts calling from the fp value...
我的选项已经用完了,我不会完全理解最后一个代表发生了什么事情,除了事实上它与其他代表有点复杂。
我真的不明白为什么实例方法调用的地址不同于其他两个地址,任何人都可以帮助我?
using System;
using System.Linq;
namespace Test
{
internal class Program
{
private static void Main(string[] args)
{
var obj = new SomethingObj();
var firstDel = (_SetSomething) Delegate.CreateDelegate(typeof (_SetSomething), obj, "SetSomething");
var targetFind = typeof (SomethingObj).GetMethod("Find");
var secondDel = (_Find) Delegate.CreateDelegate(typeof (_Find), obj, targetFind, true);
var targetAdd = typeof (SomethingObj).GetMethods()
.First(m => m.Name == "AddSomething" && m.GetParameters().Length == 0)
.MakeGenericMethod(typeof (SomeStuff));
var thirdDel =
(_AddSomething<SomeStuff>) Delegate.CreateDelegate(typeof (_AddSomething<SomeStuff>), obj, targetAdd, true);
var firstAddress = firstDel.Method.MethodHandle.GetFunctionPointer();
var secondAddress = secondDel.Method.MethodHandle.GetFunctionPointer();
var thirdAddress = thirdDel.Method.MethodHandle.GetFunctionPointer();
obj.SetSomething(true); // E8 XX XX XX XX calling exactly the first address got from the delegate
firstDel.DynamicInvoke(true); // starts calling from the fp value
var ret1 = obj.Find("something"); // E8 XX XX XX XX calling exactly the second address from the delegate
var ret2 = secondDel.DynamicInvoke("something"); // starts calling from the fp value
var ret3 = obj.AddSomething<SomeStuff>(); // E8 XX XX XX XX !!! Here the address does not match with the function pointer got from delegate
var ret4 = thirdDel.DynamicInvoke(null); // starts calling from the fp value...
}
public class SomethingObj
{
public void SetSomething(bool value)
{
}
public SomeStuff AddSomething(Type type)
{
return new SomeStuff();
}
public T AddSomething<T>() where T : SomeStuff
{
return new SomeStuff() as T;
}
public SomeStuff AddSomething(string className)
{
return new SomeStuff();
}
public SomeStuff Find(string value)
{
return new SomeStuff();
}
}
public class SomeStuff
{
}
public class SomeStuffTest : SomeStuff
{
}
private delegate void _SetSomething(bool value);
private delegate SomeStuff _Find(string value);
private delegate T _AddSomething<T>();
}
}