Hãy để tôi bắt đầu bằng cách nói rằng tôi đã xem và tìm thấy mô tả về việc sử dụng cố định {}, Marshal.AllocHGlobal() và GCHandle .Alloc() trong diễn đàn này và trong nhiều liên kết trên web. Tuy nhiên, tôi vẫn chưa tìm được lời giải thích ngắn gọn về thời điểm sử dụng lớp Marshal so với lớp GCHandle (có và không sử dụng cố định {}).Hiểu sự khác biệt giữa việc sử dụng cố định {}, Marshal.AllocHGlobal() và GCHandle.Alloc()
Tôi đang sử dụng thư viện .NET của bên thứ ba có phương thức được gọi là Readline() trong lớp "Bộ đệm". Sách hướng dẫn hiển thị mẫu thử nghiệm chức năng sau:
bool ReadLine (int x1, int y1, int x2, int y2, System.IntPtr bufData, out int numRead);
với một mô tả của bufData nói rằng: ... Diện tích bộ nhớ phải có một số byte lớn hơn hoặc bằng với lần chiều dài dòng giá trị trả về bởi tài sản BytesPerPixel.
Bây giờ sau trong cuốn hướng dẫn sử dụng họ làm đưa ra một ví dụ về truy cập vào bộ đệm (mà tôi đã điều chỉnh một chút cho ví dụ cụ thể của tôi):
// Create an array large enough to hold one line from buffer
int size = 640;
byte[] dataLine = new byte[size * 2]; // 2 bytes per pixel
// Pin the array to avoid Garbage collector moving it
GCHandle dataLineHandle = GCHandle.Alloc(dataLine, GCHandleType.Pinned);
IntPtr dataLineAddress = dataLineHandle.AddrOfPinnedObject();
và tôi có thể làm theo các trên "Ví dụ" mã với:
// Read one line of buffer data
success = buffer.ReadLine(0, 0, 639, 0, dataLineAddress, out numRead);
// Unpin the array
dataLineHandle.Free()
đó có thể là sự kết thúc của câu chuyện (và tôi vẫn chưa kiểm tra mã trên), nhưng tôi đã kết thúc googling lớp GCHandle mà chở tôi xuống con đường của .NET interoperab ility, PInvoke vv
Vì vậy, câu hỏi của tôi ... 1) Tại sao tôi không thể sử dụng:
IntPtr dataLineAddress = Marshal.AllocHGlobal(size * 2);
và vượt qua đó vào ReadLine()?
2) Tôi có thể cũng sử dụng đoạn mã sau đây (trích xuất và chỉnh từ các ví dụ trên web):
int size = 640;
byte[] dataLine= new byte[size * 2]; // 2 bytes per pixel
// prevent garbage collector from moving buffer around in memory
fixed (byte* fixedDataLine = dataLine)
{
// get IntPtr representing address of first buffer element
IntPtr dataLineAddress= Marshal.UnsafeAddrOfPinnedArrayElement(fixedDataLine , 0);
success = buffer.ReadLine(0, 0, 639, 0, dataLineAddress, out numRead);
}
Tôi muốn được quan tâm trong bất cứ ai có thể làm sáng tỏ về các kỹ thuật nói trên và chỉ ra các lỗi của tôi trong việc triển khai cũng như chỉ ra khi các phương pháp trên phù hợp. Cuối cùng, ngay cả khi các phương pháp trên đều hợp lệ, có một sự thúc đẩy chung trong vài năm qua đối với một cách tiếp cận này hay cách khác không?
Cảm ơn trước !! Hyped
Điều đó nghe giống như một API khủng khiếp. – SLaks