Search code examples
c#arrayscopymarshallingintptr

Marshal.Copy, copying an array of IntPtr into an IntPtr


I can't figure out how does the Copy(IntPtr[], Int32, IntPtr, Int32) method works. I though it could copy the data contained in multiple IntPtrs into a single IntPtr (as MSDN states) but apparently it doesn't work as I expected:

IntPtr[] ptrArray = new IntPtr[]
{
    Marshal.AllocHGlobal(1),
    Marshal.AllocHGlobal(2)
 };

 Marshal.WriteByte(ptrArray[0], 0, 0xC1);

 // Allocate the total size.
 IntPtr ptr = Marshal.AllocHGlobal(3);

 Marshal.Copy(ptrArray, 0, ptr, ptrArray.Length);

 // I expect to read 0xC1 but Value is always random!!
 byte value = Marshal.ReadByte(ptr, 0);

Does someone know if I'm using this method for something that it is not its purpose?


Solution

  •     static void Main(string[] args)
        {
            IntPtr[] ptrArray = new IntPtr[]
            {
                Marshal.AllocHGlobal(1),
                Marshal.AllocHGlobal(2)
            };
    
            Marshal.WriteByte(ptrArray[0], 0, 100);
    
            int size = Marshal.SizeOf(typeof(IntPtr)) * ptrArray.Length;
            IntPtr ptr = Marshal.AllocHGlobal(size);
    
            Marshal.Copy(ptrArray, 0, ptr, ptrArray.Length);
    
            // Now we have native pointer ptr, which points to two pointers,
            // each of thme points to its own memory (size 1 and 2).
    
            // Let's read first IntPtr from ptr:
            IntPtr p = Marshal.ReadIntPtr(ptr);
    
            // Now let's read byte from p:
            byte b = Marshal.ReadByte(p);
    
            Console.WriteLine((int)b);    // prints 100
    
            // To do: release all IntPtr
        }
    

    Read explanations in the comments.