arasındaki farkları anlama Sabit {}, Marshal.AllocHGlobal() ve GCHandle kullanımının açıklamalarını inceledim ve buldum diyerek başlayalım. .Alloc() bu forum boyunca ve web üzerinde birçok linkte. Ancak, Mareşal sınıfının GCHandle sınıfına ne zaman kullanılacağını (sabit {} kullanarak ve kullanmadan) kısa bir açıklama henüz bulamadım.Sabit {}, Marshal.AllocHGlobal() ve GCHandle.Alloc()
Bir "Buffer" sınıfında Readline() adlı bir yöntemi olan bir üçüncü taraf .NET kitaplığı kullanıyorum. Bu kılavuz aşağıdaki prototipini gösterir:
bool ReadLine (int x1, int y1, int x2, int y2, System.IntPtr bufData, int intRead); diyor bufData ilgili bir açıklama da
: ... bellek alanı satır uzunluğu zamanlarda BytesPerPixel özelliği tarafından döndürülen değeri eşit veya büyük bayt numarası olmalıdır.
Şimdi sonradan kılavuzdaki onlar (benim özel örnek vermek gerekirse biraz küçük değişiklikler yaptık) tampon erişen bir örnek vermek yapmak :
// 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();
ve yukarıda takip edebilir "örnek" kod ile:
hikayenin sonu olabilir// Read one line of buffer data
success = buffer.ReadLine(0, 0, 639, 0, dataLineAddress, out numRead);
// Unpin the array
dataLineHandle.Free()
(ve ben yukarıdaki kodu test henüz), ama .NET yolunu beni sürdü GCHandle sınıfını googling sona erdi interoperab vb ility, PInvoke,
Yani benim sorular ... 1) Neden kullanamazsınız:IntPtr dataLineAddress = Marshal.AllocHGlobal(size * 2);
ve) (taleb içine geçmesi?
2) Ayrıca aşağıdaki kod parçacığını (web'de örneklerden çıkarılan ve tweaked) kullanabilir miyim: Yukarıdaki teknikler ışık tutacak ve işaret edebilir
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);
}
kimseye ilgilerini çekebilir Uygulamamdaki hatalarımın yanı sıra yukarıdaki yöntemler uygun olduğunda da işaret ediyor. Son olarak, yukarıdaki yöntemler geçerli olsa bile, son birkaç yılda bir yaklaşıma ya da diğerine yönelik genel bir itici güç var mı?
Şimdiden teşekkürler! Hyped
Bu, korkunç bir API'ye benziyor. – SLaks