[英]Implementing Win32 FileWrite
[DllImport("kernel32.dll", SetLastError=true)]
public static extern unsafe bool WriteFile(IntPtr hFile, void* lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, IntPtr lpOverlapped);
我正在通過帶有簽名的Write(..)方法實現此目的:
Write(IntPtr handleFile, void* bufferData, uint length){
void* buffer = bufferData
while (length > 0)
{
uint wrtn;
if (!WriteFile(handle, buffer, len, out wrtn, IntPtr.Zero))
{
// Do some error handling
}
// THIS DOESNT WORK!
// I want to move along the buffer to be able to write its remainder...
// I tried many variations of this as well, but it seems even '+' is not valid for a void*
buffer += wrtn;
len -= wrtn;
}
}
正如我通過查看該內容(討論讀取對象的用法)所獲悉的那樣,我需要在代碼中實現while循環,因為緩沖區的寫入/讀取可能不會一in而就。 這是問題開始的地方:
如果我想保留我的C#方法簽名以接受void *,則不同於鏈接的Read示例,在該示例中,byte *被接受為緩沖區的參數。
這意味着在傳遞WriteFile一遍之后,我應該將void *移到尚未寫入的緩沖區的開頭。 我顯然不能通過僅使用包含已寫入字節數的uint來遞增void *來做到這一點...我知道void *沒有預定的大小,因此無法進行遞增,但是我想知道接下來應該如何實現我在努力
您應該能夠將buffer
轉換為byte*
,然后再遞增。 空指針沒有大小相關聯,因此,如果您想在任何方向上移動一定數量的字節,可以將其強制轉換為其他類型的指針(任何類型的指針),然后使用強制轉換類型的大小在指針算術中,如下所示:
buffer = (void *)((byte*)buffer + wrtn);
上面的行將buffer
強制轉換為字節指針,然后將其位置增加wrtn
個字節,然后將新指針強制轉換回void *。 當然,如果要執行任意指針算術,則強制轉換為byte*
是顯而易見的選擇。
另一種可能性是一直將buffer
視為一個byte*
,並且僅在將其傳遞給WriteFile
時才將其WriteFile
為void*
Write(IntPtr handleFile, void* bufferData, uint length)
{
byte* buffer = (byte*)bufferData;
while (length > 0)
{
uint wrtn;
if (!WriteFile(handle, (void*)buffer, len, out wrtn, IntPtr.Zero))
{
// Do some error handling
}
buffer += wrtn;
len -= wrtn;
}
}
並且,作為最后的建議,我將考慮完全更改Write
的簽名以使用byte*
而不是void*
因為這將使其與來自C#的其他調用者更加兼容,並且在這種情況下, byte*
更有意義。 您不必擔心使其與WriteFile本機API的簽名相匹配,因為在傳入時可以將如上所示的byte*
強制轉換為void*
。
Write(IntPtr handleFile, byte* bufferData, uint length)
{
while (length > 0)
{
uint wrtn;
if (!WriteFile(handle, (void*)bufferData, len, out wrtn, IntPtr.Zero))
{
// Do some error handling
}
bufferData+= wrtn;
len -= wrtn;
}
}
las,我必須同意其中一位評論者的意見。 你為什么做這個? 使用許多面向流的類,有更好的方法可以用c#完成文件寫入。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.