2009-09-21 103 views
48

我试图建立ReadFile异步运行,并根据MSDN,我需要设置lpNumberOfBytesReadnull:“使用NULL这个参数,如果这是一个异步操作,以避免潜在的错误结果”IntPtr.Zero是否等于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 
); 

和我这样称呼它(与具有第四参数是空值的意图):

Win32API.ReadFile(readHandle, out data_read, Win32API.BUFFER_SIZE, IntPtr.Zero, ref over_lapped); 

意志与使用null调用它相同吗?如果不是,我应该在声明或函数调用中更改哪些内容?

我也好奇,如果我应该使用SafeHandleHandleRef代替IntPtrhFile参考?我知道要确保在完成后关闭手柄CloseHandle(IntPtr),只是不确定是否有其他原因使用IntPtr以上的其他两个选项。我也试着避免使用不安全的代码。

编辑:事实证明,我不应该设置第四个参数IntPtr.Zero无论如何,因为即使我异步运行,它仍然可以立即返回。见Asynchronous Disk I/O。啊,我喜欢矛盾的故事。

回答

60

对于您列出的P/Invoke目的,您应该使用IntPtr.Zero代替NULL。请注意,这不等同于C#null关键字,但是。

6

您不能将null分配给值类型。引用类型可以为null,因为在不引用对象实例的情况下,值类型始终具有值。

IntPtr.Zero只是一个表示空指针的常量值。

6

要知道,有在C#> = 2.0的错误(功能?),其中

if (IntPtr.Zero == null) 
{ 
    // Won't enter here 
} 

会被正确编译,但在if它永远不会进入。

Microsoft connect上有一个bug,但它已经很老了,并且没有任何来自微软人员的评论。

+12

对不起,因为IntPtr.Zero不等于null,所以if语句无效。 – Kobunite 2013-04-04 08:31:20

+0

@Kobunite然后尝试编写'if(IntPtr.Zero ==“Hello”)'看看会发生什么。会有一个编译时错误...问题是没有警告,比较是不可能的,也没有错误。该代码仅由编译器删除。看到生成的IL代码http://goo.gl/6zpPxN – xanatos 2015-09-02 15:40:35

+0

对不起,但它编译,因为它有效地使用'=='操作符重载隐式转换为'(IntPtr?)IntPtr.Zero ==(IntPtr? )null' – Marc 2015-12-11 20:00:37