我正在尝试设置ReadFile
以异步方式运行,并且根据MSDN,我需要将lpNumberOfBytesRead
设置为null
:
“如果这是一个异步操作,则为此参数使用NULL,以避免可能出现错误的结果。”
例如,如果我有以下内容:
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool ReadFile(
IntPtr hFile,
out byte[] aBuffer,
int cbToRead,
IntPtr cbThatWereRead,
ref OVERLAPPED pOverlapped
);
并且我这样称呼它(意图使第4个参数为null):
Win32API.ReadFile(readHandle, out data_read, Win32API.BUFFER_SIZE, IntPtr.Zero, ref over_lapped);
是否与使用null调用它相同?如果没有,我应该在声明或函数调用本身中更改什么?
我也很好奇我是否应该使用SafeHandle
或HandleRef
代替IntPtr
hFile
参考?我知道要确保在完成操作时用CloseHandle(IntPtr)
关闭句柄,只是不确定是否有其他理由在IntPtr
上使用其他两个选项。我也在努力避免使用不安全的代码。
编辑:事实证明,我不应该将第四个参数设置为IntPtr.Zero
,因为即使我是异步运行,它仍然可以立即返回。见Asynchronous Disk I/O。啊,我喜欢自相矛盾的故事。
答案 0 :(得分:69)
对于您列出的P / Invoke目的,您应该使用IntPtr.Zero
代替NULL
。但请注意,这不等同于C#null
关键字。
答案 1 :(得分:8)
您不能将null分配给值类型。 reference-type可以为null,如未引用对象实例,但value-type始终具有值。
IntPtr.Zero只是一个表示空指针的常量值。
答案 2 :(得分:7)
请注意C#> = 2.0中存在错误(功能??),其中
if (IntPtr.Zero == null)
{
// Won't enter here
}
将正确编译,但不会输入if
。
我在github of roslyn上打开了一个问题,他们回复说他们不会修复它,因为有些项目是使用警告 - 错误构建的。仍然有一个部分修复:有strict
编译模式生成此警告:
<Features>strict</Features>