C#: получение и использование IntPtr* посредством отражения

В настоящее время я работаю над некоторым кодом, который отражает структуры, которые возвращаются из вызовов в собственную dll. Некоторые структуры содержат поля IntPtr*, указывающие на массивы указателей, оканчивающихся нулем. Эти поля требуют специальной обработки. Размышляя над структурами, я могу распознать эти поля, потому что они помечены настраиваемым атрибутом.

Ниже показано, что я пытаюсь сделать:

public void ProcessStruct(object theStruct)
{
    foreach (FieldInfo fi in theStruct.GetType().GetFields(BindingFlags.Public |  BindingFlags.Instance))
    {
        if (fi.FieldType.IsPointer && IsNullTermArray(fi))
        {
            //Has the custom attribute, commence processing of 
            //IntPtr* pointing to null-terminated array
            ProcessIntPtr(fi.GetValue(theStruct));
        }
        else{/*..Other Processing..*/  }
    }
}
public void unsafe ProcessIntPtr(IntPtr* ptr)
{
    //Iterate over the array and process the elements
    //There are pointer operations here.
}

Проблема в том, что

  fi.GetValue(theStruct)

возвращает объект, который я, очевидно, не могу передать непосредственно в ProcessIntPtr(). Я не могу изменить сигнатуру ProcessIntPtr(), чтобы принять объект, так как тогда я не смогу выполнять требуемые операции с указателем. Очевидно, я также не могу привести объект к IntPtr*.

Какие методы доступны для решения этой проблемы?


person Odrade    schedule 14.07.2009    source источник


Ответы (2)


Хотя вы, возможно, не сможете выполнить преобразование из Object в IntPtr*, вы можете выполнить преобразование в IntPtr. Помните, что IntPtr* — это просто указатель-указатель. Таким образом, вы можете добраться до первого указателя, а затем вернуть его обратно.

var ptr1 = (IntPtr)(fi.GetValue(theStruct));
var ptr2 = (IntPtr*)(ptr1);
person JaredPar    schedule 14.07.2009
comment
Я не эксперт в этом, но я думаю, вам может понадобиться использовать unsafe{ } здесь.. верно? - person Stan R.; 14.07.2009
comment
@Stan R, я тоже, но да, потребуется какой-то небезопасный способ. - person JaredPar; 14.07.2009
comment
@Jared: Это кажется на шаг ближе к тому, что мне нужно, но вызывает недопустимое исключение приведения в первой строке. - person Odrade; 14.07.2009
comment
@David, какой тип, если вы выберете fi.GetValue(theStruct).GetType() - person JaredPar; 14.07.2009
comment
@ Джаред, это System.Reflection.Pointer. Я понял, что мне нужно вызвать Pointer.Unbox(). Спасибо за вашу помощь. - person Odrade; 14.07.2009

Чтобы добавить к ответу JaredPar, взгляните на класс Marshal в .NET, у него может быть много полезных функций для вас.

Ссылка на MSDN

person Stan R.    schedule 14.07.2009