2014-11-27 3 views
4

Copy(IntPtr[], Int32, IntPtr, Int32) 메서드는 어떻게 작동하는지 알 수 없습니다. I는 (MSDN 상태로) 하나를 IntPtr로 여러 IntPtrs에 포함 된 데이터를 복사 할 수 있지만 예상대로 분명히 작동하지 않습니다하지만 :이 방법을 사용하고있는 경우Marshal.Copy, IntPtr 배열을 IntPtr에 복사

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); 

사람이 알고 있나요 그것의 목적이 아닌 무엇인가?

+0

IntPtr ptr = Marshal.AllocHGlobal (3 * sizeof (IntPtr)); – Guillaume

+0

복사중인 것을 명심하십시오. 포인터가 가리키는 값이 아니라 포인터 값만 복사하는 것입니다. 임의로 Marshal.ReadByte (Marshal.ReadIntPtr (ptr), 0)는 해당 바이트를 반환합니다. 그러나 분명히 당신이 염두에 두었던 것이 아닙니다. –

답변

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

의견에 대한 설명을 읽으십시오.

+0

맞다면 [Marshal.Copy 메서드 (IntPtrArray, Int32, IntPtr, Int32)]에 대한 주석을 찾을 수 있습니다 (http://msdn.microsoft.com/en-us/library/vstudio/ms146638%28v=vs .100 % 29.aspx) : _Copies 데이터를 1 차원에서 관리되는 IntPtr 배열에서 관리되지 않는 메모리 포인터로 오히려 오히려 오해의 소지가 있지만 포인터가 복사됩니다 ..!? - 또한 : 이것은 인접한 메모리 영역을 생성하지 않으므로 임의의 바이트에 액세스하는 것은 번거롭거나 올바르게 작동 할 것입니다. – TaW

+0

이 방법은 관리되지 않는 메모리 영역에 포인터를 복사한다는 것을 의미합니다. 각 포인터는 다른 메모리를 가리킬 수 있습니다. 두 개의 다른 관리되지 않는 배열을 포함하는 배열을 원할 경우 3 바이트를 할당하고 Marshal.Copy 메서드 (IntPtr, Byte [], Int32, Int32)를 두 번 적용하십시오. –

+0

정정 : 먼저'IntPtr'을 2 개의 관리 된'byte' 배열로 읽어 들여야합니다 : Marshal.Copy 메서드 (IntPtr, Byte [], Int32, Int32)'그런 다음 3 바이트 비 관리 블록으로 복사하고, 두 번'Marshal.Copy 메서드 (Byte [], Int32, IntPtr, Int32)'. 또는 CopyMemory API (관리되지 않는 두 개의 메모리 블록간에 직접 복사)를 사용하십시오. –