2013-04-12 46 views
24

Tôi có hai giá trị IntPtr trỏ đến một số vùng dữ liệu của length byte. length có thể có thứ tự từ 200k đến 400k.Sao chép dữ liệu từ từ IntPtr sang IntPtr

  int length = /* ..*/ 
      IntPtr ptrSrc = /*.. */; 
      IntPtr ptrDst = /* .. */; 

Bây giờ tôi muốn sao chép dữ liệu từ ptrSrc đến ptrDst. Mã này hoạt động tốt:

  byte[] data = new byte[length]; 
      Marshal.Copy(ptrSrc, data, 0, length); 
      Marshal.Copy(data, 0, ptrDst, length); 

nhưng có nhược điểm là cần thêm một mảng tạm thời (có khả năng lớn). Thật không may, tôi không thể tìm thấy biến thể Marshal.Copy trong khuôn khổ .NET để sao chép trực tiếp từ IntPtr đến IntPtr, vì vậy tôi đang tìm kiếm các giải pháp thay thế.

Tôi quan tâm đến một giải pháp hoạt động trên 32 Windows cũng như Windows 64 bit. Bất kỳ đề xuất?

+1

Bạn có thể sử dụng 'không an toàn' không? – driis

+0

@driis: vâng, điều đó là có thể. –

Trả lời

32

Bạn có thể P/Gọi hàm C thích hợp. Đó có lẽ là cách dễ nhất để làm điều đó. Ví dụ:

class Program 
{ 
    [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)] 
    public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); 

    static void Main() 
    { 
     const int size = 200; 
     IntPtr memorySource = Marshal.AllocHGlobal(size); 
     IntPtr memoryTarget = Marshal.AllocHGlobal(size); 

     CopyMemory(memoryTarget,memorySource,size); 
    } 
} 
+0

Hm, điều đó có hoạt động trên 32 cũng như Windows 64 bit không? –

+0

Có. 'memcpy' sao chép các byte, do đó không có vấn đề về kích thước con trỏ hoặc từ ranh giới. C# marhsalling sẽ chăm sóc việc cung cấp kích thước con trỏ đúng cho hàm C bên dưới. – driis

+0

Và tôi có thể giả định msvcrt được cài đặt trên máy của người dùng không, hoặc tôi có phải cung cấp cho riêng mình không? Tôi có nghĩa là, có msvcrt.dll khác nhau cho 32 và 64 bit Windows, phải không? Tôi không lo lắng về kích thước con trỏ. –

3

Tôi nghĩ câu trả lời cần một bản cập nhật trong .net 4.6 có

Buffer.MemoryCopy Method (Void*, Void*, Int64, Int64) 

Phương pháp này bản sourceBytesToCopy byte từ địa chỉ được xác định bởi nguồn đến địa chỉ theo quy định của đích. Nếu vùng đệm trùng lặp và chênh lệch giữa nguồn đích đích nhỏ hơn sourceBytesToCopy, khối nguồn được sao chép vào khối đích theo thứ tự ngược lại.

Vì vậy, nếu bạn không sử dụng 4.6 hoặc cửa sổ ứng dụng phổ dụng thì hãy sử dụng câu trả lời trước đó.

+0

Cảm ơn bạn đã cập nhật này. Chắc chắn giải pháp này cũng hoạt động cho các ứng dụng UWP? Tôi đoán câu trả lời được chấp nhận sẽ không. –

+0

Nó yêu cầu khối mã không an toàn để hoạt động. – SMUsamaShah

+0

Có điều đó bình thường khi bạn ở trong C# và truy cập bộ nhớ trực tiếp. C# không phải là C++ khi các hành động như vậy phổ biến hơn – user3800527

Các vấn đề liên quan