簡體   English   中英

實現Win32 FileWrite

[英]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時才將其WriteFilevoid*

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM