Ejemplo n.º 1
0
        // this function takes a pointer to a templated array (ie. a pointer to a list of Types, and a length)
        // and returns an array of that object type, and cleans up the memory if specified.
        public static object GetTemplatedArray(IntPtr sourcePtr, Type structureType, bool freeMem)
        {
            templated_array arr = (templated_array)Marshal.PtrToStructure(sourcePtr, typeof(templated_array));

            if (structureType == typeof(byte))
            {
                byte[] val = new byte[arr.count];
                if (val.Length > 0)
                {
                    Marshal.Copy(arr.elems, val, 0, val.Length);
                }
                return(val);
            }
            else
            {
                Array val = Array.CreateInstance(structureType, arr.count);

                int sizeInBytes = SizeOf(structureType);

                for (int i = 0; i < val.Length; i++)
                {
                    IntPtr p = new IntPtr((arr.elems.ToInt64() + i * sizeInBytes));

                    val.SetValue(PtrToStructure(p, structureType, freeMem), i);
                }

                if (freeMem)
                {
                    RENDERDOC_FreeArrayMem(arr.elems);
                }

                return(val);
            }
        }
Ejemplo n.º 2
0
        // specific versions of the above GetTemplatedArray for convenience.
        public static string TemplatedArrayToString(IntPtr sourcePtr, bool freeMem)
        {
            templated_array arr = (templated_array)Marshal.PtrToStructure(sourcePtr, typeof(templated_array));

            string val = PtrToStringUTF8(arr.elems, arr.count);

            if (freeMem)
            {
                RENDERDOC_FreeArrayMem(arr.elems);
            }

            return(val);
        }
Ejemplo n.º 3
0
        public static string[] TemplatedArrayToStringArray(IntPtr sourcePtr, bool freeMem)
        {
            templated_array arr = (templated_array)Marshal.PtrToStructure(sourcePtr, typeof(templated_array));

            int arrSize = SizeOf(typeof(templated_array));

            string[] ret = new string[arr.count];
            for (int i = 0; i < arr.count; i++)
            {
                IntPtr ptr = new IntPtr((arr.elems.ToInt64() + i * arrSize));

                ret[i] = TemplatedArrayToString(ptr, freeMem);
            }

            if (freeMem)
            {
                RENDERDOC_FreeArrayMem(arr.elems);
            }

            return(ret);
        }
Ejemplo n.º 4
0
        // take a pointer to a C++ structure of a given type, and convert it into the managed equivalent,
        // while handling alignment etc and freeing memory returned if it should be caller-freed
        private static object PtrToStructure(IntPtr sourcePtr, Type structureType, bool freeMem, bool isUnion)
        {
            if (sourcePtr == IntPtr.Zero)
            {
                return(null);
            }

            // Get instance fields of the structure type.
            FieldInfo[] fields = structureType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

            object ret = Activator.CreateInstance(structureType);

            try
            {
                for (int fieldIdx = 0; fieldIdx < fields.Length; fieldIdx++)
                {
                    FieldInfo field = fields[fieldIdx];

                    IntPtr fieldPtr = isUnion ? sourcePtr : OffsetPtr(structureType, fields, fieldIdx, sourcePtr);

                    var arrayType   = NonArrayType(field.FieldType);
                    int sizeInBytes = SizeOf(arrayType);

                    // no custom attribute, so just use the regular Marshal code
                    var cma = GetCustomAttr(structureType, fields, fieldIdx);
                    if (cma == null)
                    {
                        if (field.FieldType.IsEnum)
                        {
                            field.SetValue(ret, (VarType)Marshal.ReadInt32(fieldPtr));
                        }
                        else
                        {
                            field.SetValue(ret, Marshal.PtrToStructure(fieldPtr, field.FieldType));
                        }
                    }
                    else
                    {
                        switch (cma.CustomType)
                        {
                        case CustomUnmanagedType.CustomClass:
                            field.SetValue(ret, PtrToStructure(fieldPtr, field.FieldType, freeMem));
                            break;

                        case CustomUnmanagedType.CustomClassPointer:
                            IntPtr ptr = Marshal.ReadIntPtr(fieldPtr);
                            if (ptr == IntPtr.Zero)
                            {
                                field.SetValue(ret, null);
                            }
                            else
                            {
                                field.SetValue(ret, PtrToStructure(ptr, field.FieldType, freeMem));
                            }
                            break;

                        case CustomUnmanagedType.Union:
                            field.SetValue(ret, PtrToStructure(fieldPtr, field.FieldType, freeMem, true));
                            break;

                        case CustomUnmanagedType.Skip:
                            break;

                        case CustomUnmanagedType.FixedArray:
                        {
                            if (cma.FixedType == CustomFixedType.Float)
                            {
                                float[] val = new float[cma.FixedLength];
                                Marshal.Copy(fieldPtr, val, 0, cma.FixedLength);
                                field.SetValue(ret, val);
                            }
                            else if (cma.FixedType == CustomFixedType.UInt16)
                            {
                                Int16[] val = new Int16[cma.FixedLength];
                                Marshal.Copy(fieldPtr, val, 0, cma.FixedLength);
                                UInt16[] realval = new UInt16[cma.FixedLength];
                                for (int i = 0; i < val.Length; i++)
                                {
                                    realval[i] = unchecked ((UInt16)val[i]);
                                }
                                field.SetValue(ret, val);
                            }
                            else if (cma.FixedType == CustomFixedType.Int32)
                            {
                                Int32[] val = new Int32[cma.FixedLength];
                                Marshal.Copy(fieldPtr, val, 0, cma.FixedLength);
                                field.SetValue(ret, val);
                            }
                            else if (cma.FixedType == CustomFixedType.Double)
                            {
                                double[] val = new double[cma.FixedLength];
                                Marshal.Copy(fieldPtr, val, 0, cma.FixedLength);
                                field.SetValue(ret, val);
                            }
                            else if (cma.FixedType == CustomFixedType.UInt32)
                            {
                                Int32[] val = new Int32[cma.FixedLength];
                                Marshal.Copy(fieldPtr, val, 0, cma.FixedLength);
                                UInt32[] realval = new UInt32[cma.FixedLength];
                                for (int i = 0; i < val.Length; i++)
                                {
                                    realval[i] = unchecked ((UInt32)val[i]);
                                }
                                field.SetValue(ret, realval);
                            }
                            else
                            {
                                Array val = Array.CreateInstance(arrayType, cma.FixedLength);

                                for (int i = 0; i < val.Length; i++)
                                {
                                    IntPtr p = new IntPtr((fieldPtr.ToInt64() + i * sizeInBytes));

                                    val.SetValue(PtrToStructure(p, arrayType, freeMem), i);
                                }

                                field.SetValue(ret, val);
                            }
                            break;
                        }

                        case CustomUnmanagedType.UTF8TemplatedString:
                        case CustomUnmanagedType.TemplatedArray:
                        {
                            // templated_array must be pointer-aligned
                            long alignment = fieldPtr.ToInt64() % IntPtr.Size;
                            if (alignment != 0)
                            {
                                fieldPtr = new IntPtr(fieldPtr.ToInt64() + IntPtr.Size - alignment);
                            }

                            templated_array arr = (templated_array)Marshal.PtrToStructure(fieldPtr, typeof(templated_array));
                            if (field.FieldType == typeof(string))
                            {
                                if (arr.elems == IntPtr.Zero)
                                {
                                    field.SetValue(ret, "");
                                }
                                else
                                {
                                    field.SetValue(ret, PtrToStringUTF8(arr.elems, arr.count));
                                }
                            }
                            else
                            {
                                if (field.FieldType.IsArray && arrayType == typeof(byte))
                                {
                                    byte[] val = new byte[arr.count];
                                    if (val.Length > 0)
                                    {
                                        Marshal.Copy(arr.elems, val, 0, val.Length);
                                    }
                                    field.SetValue(ret, val);
                                }
                                else if (field.FieldType.IsArray)
                                {
                                    Array val = Array.CreateInstance(arrayType, arr.count);

                                    for (int i = 0; i < val.Length; i++)
                                    {
                                        IntPtr p = new IntPtr((arr.elems.ToInt64() + i * sizeInBytes));

                                        val.SetValue(PtrToStructure(p, arrayType, freeMem), i);
                                    }

                                    field.SetValue(ret, val);
                                }
                                else
                                {
                                    throw new NotImplementedException("non-array element marked to marshal as TemplatedArray");
                                }
                            }
                            if (freeMem)
                            {
                                RENDERDOC_FreeArrayMem(arr.elems);
                            }
                            break;
                        }

                        default:
                            throw new NotImplementedException("Unexpected attribute");
                        }
                    }
                }

                MethodInfo postMarshal = structureType.GetMethod("PostMarshal", BindingFlags.NonPublic | BindingFlags.Instance);
                if (postMarshal != null)
                {
                    postMarshal.Invoke(ret, new object[] { });
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.Fail(ex.Message);
            }

            return(ret);
        }