2015-06-18 2 views
1

Я хочу вызвать с отражением каждый метод класса, но я не могу вызвать методы с указателем в качестве ссылки. Обычно я просто могу передать null для каждого указателя, который я нахожу, и все будет хорошо. Проблема заключается в том, когда функция пытается получить доступ к моему пройденному указателю. Указатель будет ссылкой на адрес памяти 0, и это, очевидно, мгновенный сбой для моей Программы. Поэтому мне нужно передать указатель на действительный адреса памяти, но я не знаю, как я могу создать указатель во время выполненияC# Метод вызова рефлексии с параметром ref/Pointer

сжатая версия моего кода:

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() }); 
    } 
} 

И TestClass:

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

     } 

     public void Test2(ref int reference) 
     { 

     } 
} 

Я всегда получаю исключение «System.RuntimeType» не может быть преобразовано в тип странная вещь «System.Char *» является то, что pointerInstance.GetType(). MakePointerType() возвращает символ *, именно то, что Мне нужно перейти в удовольствие ction ...

+2

Объявление метода недействительно для начала - вы не указали тип параметра. ('ref' - это модификатор, а не тип.) Если бы вы могли предоставить короткую, но * полную * программу, демонстрирующую проблему, это очень помогло бы. Кроме того, я предлагаю вам попробовать с * просто * параметром ref или * просто * указательным параметром - иначе вы не узнаете, какой из них неисправен ... –

+0

Я отредактировал свой пост и сжал код – Djeurissen

+0

Но все же не включен короткую, но полную программу, которую я могу просто скопировать, вставить, скомпилировать и запустить. И работает ли 'ref' версия? Если это так, удалите его - лучше было бы сосредоточиться на * одной * проблеме, а не показывать два. –

ответ

8

Прежде всего, давайте разберем это в указателе vs ref - они обрабатываются несколько иначе.

Это не ясно, что указатель значения вы ожидаетесь метод для приема - в частности, в качестве значения, переданного Invoke был типом, а не экземпляр типа - но вы должны использовать 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'; 
    } 
} 

Выход:

Received: x 
After call, c = y 

ref для параметров, это немного проще - вы просто позволить для нормального бокса, а массив аргументов изменен:

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; 
    } 
} 
+1

Первый хороший пример использования класса «Pointer», который я видел :) – leppie

+2

@leppie: Я даже не видел его до сегодняшнего дня :) –

+0

Большое спасибо. Я полностью забыл, что передал параметр типа как параметр. Но у меня все еще есть вопрос, что, если я не знаю, какой тип указателя у меня есть? Как и в моем примере, у меня есть только объект, представляющий тип – Djeurissen

Смежные вопросы