3

I'm trying to get the function pointer of a method inside of a generic class. I've been using MethodInfo.MethodHandle.GetFunctionPointer() to do so, but as I've been working with generic classes recently, the above methodology has been working the way I thought it would.

Consider the following:

public class Example<T>
{
    public bool doSomething()
    {
        /*some work*/
        return true;
    }
}

The following all return the same memory address:

typeof(Example<int>).GetMethod("doSomething").MethodHandle.GetFunctionPointer()
typeof(Example<bool>).GetMethod("doSomething").MethodHandle.GetFunctionPointer()
typeof(Example<SomeClass>).GetMethod("doSomething").MethodHandle.GetFunctionPointer()

I'm not sure why this is. Can anyone explain it to me? Is there really only one version of that function within memory?

Surely this raises some eyebrows. I am working on a modifying a game's code without access to the source. Injecting code this way is common practice in this line of work. The EULA for the game specifically allows for such injection as well, so long as the original dll file is not directly modified.

  • What are trying to do with the pointer? Do you just want to create this class and use the method ? – TheGeneral Mar 16 '18 at 02:40
  • This should shed some light: [link](https://stackoverflow.com/questions/28870696/how-do-c-net-generics-know-their-parameter-types) – John Wu Mar 16 '18 at 03:18
  • 1
    I just copy pasted your code, ran, and they all returned different pointers. – Evk Mar 16 '18 at 05:47
  • One would expect all reference type instantiations to share the same function. There was some talk in the past about also making all value types that have the same layout (w.r.t. data size and GC roots) share code but I can't recall if that's been implemented. – Damien_The_Unbeliever Mar 16 '18 at 07:18
  • I apologize, my actual code is a bit different, I figured the same bahavior would be manifest. If John Wu's link is correct, then it's because I'm using not just using reference types (like I am in my actual example). EDIT: ninja'd – Joseph Hales Mar 16 '18 at 07:19
  • Micheal, the end result would be to write my own function, maybe using il from the original function, and then rewriting th original function to be a jump to the new function. – Joseph Hales Mar 16 '18 at 07:21

1 Answers1

1

That's because, as stated in this article by Anders Hejlsberg (lead C# architect):

Now, what we then do is for all type instantiations that are value types—such as List<int>, List<long>, List<double>, List<float>—we create a unique copy of the executable native code. So List<int> gets its own code. List<long> gets its own code. List<float> gets its own code. For all reference types we share the code, because they are representationally identical. It's just pointers.

In your example, bool and int are value types. They each get their own copy and so they have different pointers to doSomething. SomeClass is reference type (I assume). So it shares its code with other reference types, but not with value types. So it also has different doSomething pointer (different from bool and int versions). If you use another reference type (SomeOtherClass) - it will have the same pointer as SomeClass version of doSomething.

Evk
  • 98,527
  • 8
  • 141
  • 191
  • The actual type that represents any reference type in the copy is `System.__Canon`. – IS4 Mar 20 '18 at 22:07