gpt4 book ai didi

c# - 托管 .NET 等同于 WinBase 的 CreateFile 和 WriteFile (kernel32.dll)

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:16:39 27 4
gpt4 key购买 nike

我正在使用旧文件格式。

该文件是使用使用 WinBase.h CreateFile() 和 WriteFile() 函数(在 kernel32.dll 中找到)的非托管 C++ 创建的。

我一直在使用 P/Invoke 互操作来访问这些 native 函数,如下所示:

    [DllImport("kernel32.dll")]
public static extern bool WriteFile(
IntPtr hFile,
byte[] lpBuffer,
uint nNumberOfBytesToWrite,
out uint lpNumberOfBytesWritten,
[In] ref NativeOverlapped lpOverlapped);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteFileEx(
IntPtr hFile,
byte[] lpBuffer,
uint nNumberOfBytesToWrite,
[In] ref NativeOverlapped lpOverlapped,
WriteFileCompletionDelegate lpCompletionRoutine);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr CreateFile(
string lpFileName, uint dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr hObject);

public delegate void WriteFileCompletionDelegate(
UInt32 dwErrorCode,
UInt32 dwNumberOfBytesTransfered,
ref NativeOverlapped lpOverlapped);

问题是当我调用 WriteFile() 时,文件总是被后续调用覆盖。

最好我想使用兼容的 .NET 等效项,它允许我生成完全相同的输出格式。

C++ 代码看起来像这样:(工作)

HANDLE hFile = CreateFile(sFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, &someVar1, sizeof(bool), &dwWritten, NULL);
WriteFile(hFile, &someVar1, sizeof(long), &dwWritten, NULL);
WriteFile(hFile, &someVar2, sizeof(bool), &dwWritten, NULL);
WriteFile(hFile, sStr.GetBuffer(0), dwStrLen*sizeof(TCHAR), &dwWritten, NULL);
CloseHandle(hFile);

C# 如下:(OVERWRITES PREVIOUS WRITE 即输出文件将仅包含“T”)

{   
var hFile = COMFileOps2.CreateFile(FILE_NAME, (uint) COMFileOps2.FILE_GENERIC_WRITE,
COMFileOps2.FILE_SHARE_WRITE, IntPtr.Zero, COMFileOps2.CREATE_ALWAYS,
COMFileOps2.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);

var natOverlap = new NativeOverlapped();

COMFileOps2.WriteFileEx(hFile, new byte[] {(byte) 't'}, 1, ref natOverlap, Callback);
COMFileOps2.WriteFileEx(hFile, new byte[] { (byte)'e' }, 1, ref natOverlap, Callback);
COMFileOps2.WriteFileEx(hFile, new byte[] { (byte)'s' }, 1, ref natOverlap, Callback);
COMFileOps2.WriteFileEx(hFile, new byte[] { (byte)'T' }, 1, ref natOverlap, Callback);

COMFileOps2.CloseHandle(hFile);

}

private static void Callback(uint dwerrorcode, uint dwnumberofbytestransfered, ref NativeOverlapped lpoverlapped)
{
throw new NotImplementedException();
}

更新:以下 C# 代码将写出“测试”:

uint written;
uint position = 0;

var natOverlap0 = new NativeOverlapped();
COMFileOps.WriteFile(hFile, new byte[] {(byte) 'T'}, 1, out written, ref natOverlap0);

position += written;
var natOverlap1 = new NativeOverlapped {OffsetLow = (int) position};
COMFileOps.WriteFile(hFile, new byte[] { (byte)'e' }, 1, out written, ref natOverlap1);

position += written;
var natOverlap2 = new NativeOverlapped { OffsetLow = (int)position };
COMFileOps.WriteFile(hFile, new byte[] { (byte)'s' }, 1, out written, ref natOverlap2);

position += written;
var natOverlap3 = new NativeOverlapped { OffsetLow = (int)position };
COMFileOps.WriteFile(hFile, new byte[] { (byte)'t' }, 1, out written, ref natOverlap3);

COMFileOps.CloseHandle(hFile);

谢谢。

最佳答案

WriteFileEx 仅异步运行,您必须为每个挂起的调用提供一个单独的 OVERLAPPED 实例,并且您必须设置 OVERLAPPED 成员,例如文件偏移量。然后,在所有操作完成之前,您不能调用 CloseHandle。并为 OVERLAPPED 使用局部变量并让它超出范围?您的数据被覆盖是最少您显示的代码可能出错的事情。

这就是为什么您的代码不起作用的原因。我不知道您为什么首先从 WriteFile 切换到 WriteFileEx。此外,从 C# 调用 Win32 API 非常不方便,尽管偶尔有必要。但首先看看 .NET 文件 API 是否满足您的需求。

由于 .NET 文件 API 倾向于使用字符串(在文本模式下,注意换行符转换等)或字节数组,您需要将其他变量转换为 byte[]。 BitConverter类是你的 friend 。

关于c# - 托管 .NET 等同于 WinBase 的 CreateFile 和 WriteFile (kernel32.dll),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2494062/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com