3

I want to call with reflection each Method of an Class but I cant call Methods with an pointer as Reference. Normally I just could pass null for each pointer I find and everything would be fine. The Problem is when the function trys to access my passed pointer. The pointer would be an reference to the memory address 0 and that is obviously an instant crash for my Program. So I need to pass an pointer to an valid memory adress, but I dont know how I can create an pointer during runtime

A compressed Version of my Code:

class Program
{
    static void Main(string[] args)
    {
        var obj = new TestClass();
        var pointerMethod = obj.GetType().GetMethod("Test");
        var referenceMethod = obj.GetType().GetMethod("Test2");

        var pointerParameter = pointerMethod.GetParameters()[0];
        var referenceParameter = referenceMethod.GetParameters()[0];

        //Get the instance of the class that is referred by the pointer/reference
        var pointerInstance = Activator.CreateInstance(pointerParameter.ParameterType.GetElementType());
        var referenceInstance = Activator.CreateInstance(referenceParameter.ParameterType.GetElementType());

        //Call the method and "cast" the char instance into an pointer
        pointerMethod.Invoke(obj, new[] {pointerInstance.GetType().MakePointerType()});
        referenceMethod.Invoke(obj, new[] { referenceInstance.GetType().MakeByRefType() });
     }
}

And TestClass:

public class TestClass
{
        unsafe public void Test(char* pointer)
        {

        }

        public void Test2(ref int reference)
        {

        }
}

I've always get the Exception "System.RuntimeType" cannot be converted to type 'System.Char*' The weird thing is that pointerInstance.GetType().MakePointerType() returns a char*, exactly that what I have to pass into the function...

6
  • 2
    Your method declaration is invalid to start with - you haven't provided a parameter type. (ref is a modifier, not a type.) If you could provide a short but complete program demonstrating the problem, that would help a lot. Also, I suggest you try with just a ref parameter or just a pointer parameter - otherwise you won't know which one is failing... Commented Jun 18, 2015 at 9:26
  • I've edited my post and compressed the code Commented Jun 18, 2015 at 10:29
  • But still not included a short but complete program I can simply copy, paste, compile and run. And does the ref version work? If so, remove it - it would be better to concentrate on one problem rather than showing two. Commented Jun 18, 2015 at 10:38
  • The ref version throws the same Exception. And the program is complete you just have to paste it into an main function...^^ Commented Jun 18, 2015 at 10:44
  • 1
    If it doesn't contain a class and method declaration, it's not complete. Why should every person trying to help you need to do that work, when you can do it once? It's really not that hard, and as you're the person asking for help, you should be the one putting in the effort. Commented Jun 18, 2015 at 10:46

1 Answer 1

10

First, let's separate this into pointer vs ref - they're handled slightly differently.

It's not clear what pointer value you expected the method to receive - particularly as the value you passed to Invoke was a type, not an instance of the type - but you should use Pointer.Box:

using System.Reflection;

class TestPointer
{    
    unsafe static void Main()
    {
        char c = 'x';
        char* p = &c;
        object boxedPointer = Pointer.Box(p, typeof(char*));

        var method = typeof(TestPointer).GetMethod("Foo");
        method.Invoke(null, new[] { boxedPointer });
        Console.WriteLine("After call, c = {0}", c);
    }

    public static unsafe void Foo(char *pointer)
    {
        Console.WriteLine("Received: {0}", *pointer);
        *pointer = 'y';
    }
}

Output:

Received: x
After call, c = y

For ref parameters, it's slightly simpler - you just allow for normal boxing, and the argument array is changed:

using System.Reflection;

class TestRef
{    
    unsafe static void Main()
    {
        var method = typeof(TestRef).GetMethod("Foo");
        var args = new object[] { 10 };
        method.Invoke(null, args);
        Console.WriteLine("After call, args[0] = {0}", args[0]);
    }

    public static unsafe void Foo(ref int x)
    {
        Console.WriteLine("Received: {0}", x);
        x = 20;
    }
}
Sign up to request clarification or add additional context in comments.

12 Comments

@leppie: I'd never even seen it before today :)
Thank you very much. I totaly forgot that I passed Type's as parameter.But I still have a question, what if I do not know which type of pointer I have? Like in my Example I only have a Object representing the Type
@Djeurissen: If you don't even know the type, where are you expecting to get a value from?
Sorry my fault. I know the type but only during runtime.
@Djeurissen: So where do you expect to get the value from?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.