В настоящее время я работаю над некоторым кодом, который отражает структуры, которые отбираются обратно из вызовов в родную 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 *.
Какие методы доступны для решения этой проблемы?
Пока вы не можете отбрасывать объект из объекта в IntPtr *, вы можете использовать его для IntPtr. Помните, IntPtr*
- это просто указатель указателя. Таким образом, вы можете перейти к первому указателю, а затем отбросить его.
var ptr1 = (IntPtr)(fi.GetValue(theStruct));
var ptr2 = (IntPtr*)(ptr1);
Чтобы добавить к ответу JaredPar, взгляните на класс Marshal в .NET, у него может быть много полезных функций для вас.