views:

441

answers:

2

I'm currently working on some code which reflects over structures that are marshaled back from calls into a native dll. Some of the structs contain IntPtr* fields that point to null-terminated arrays of pointers. These fields require special processing. When reflecting over the structs, I can recognize these fields because they are marked by a custom attribute.

The following illustrates what I'm trying to do:

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.
}

The problem is that

  fi.GetValue(theStruct)

returns an object, which I obviously can't pass directly to ProcessIntPtr(). I cannot change the signature of ProcessIntPtr() to accept an object, as then I wouldn't be able to perform the pointer operations that I require. Obviously, I also can't cast from object to IntPtr*.

What techniques are available to handle this issue?

+1  A: 

While you may not be able to cast from Object to IntPtr*, you can cast to IntPtr. Remember, IntPtr* is just a pointer pointer. So you can get to the first pointer and then cast it back.

var ptr1 = (IntPtr)(fi.GetValue(theStruct));
var ptr2 = (IntPtr*)(ptr1);
JaredPar
I am not an expert on this, but I think you might need to use unsafe{ } here..right?
Stan R.
@Stan R, neither am I but yes some manner of unsafe will be needed.
JaredPar
@Jared: This seems step closer to what I need, but it causes an invalid cast exception on the first line.
Odrade
@David, what is the type if you go fi.GetValue(theStruct).GetType()
JaredPar
@Jared, It's a System.Reflection.Pointer. I realized that I need to call Pointer.Unbox() on it. Thanks for your help.
Odrade
A: 

To add to JaredPar's answer, take a look at Marshal class in .NET , it might have a lot of useful features for you.

MSDN Link

Stan R.