一个通过Createfile()打开的串口句柄,如果有可能已经被CloseHandle()关闭,那么怎么才能判断该HANDLE是否还有效?

解决方案 »

  1.   

    当你在一个程序里面 定义一个 int a;在没赋值之前就 cout<<a;了  后果是怎么样呢??肯定有东西输出  但是东西是未知的 也为你的变量a所占据的内存里面 是有内容的我都不知道自己在说什么了 哈哈 
      

  2.   

    试一试关闭句柄之后 句柄是不是NULL
      

  3.   

    我想这还是需要写程序的时候注意。句柄变量在初始化的时候赋空。CloseHandle之后也要赋空。
    HANDLE handle = NULL;
    handle = CreateFile();
    if(handle == NULL)
    {
       //打开失败的处理
    }
    //打开成功的处理CloseHandle(handle);
    handle = NULL;
    不知楼主是否看过《高质量C++》一书。该书指针章节介绍到要杜绝
    野指针也是用了类似的方法。
    void *pVoid = NULL;
    pVoid = new int;
    if(pVoid != NULL)
    {//do something
    }
    delete pVoid;
    //pVoid = NULL;删除pVoid后没有把pVoid赋空。 if(pVoid != NULL)  //这里pVoid结成了野指针,很危险。
    {//do something
    }
      

  4.   

    你的句柄关闭后,每次都赋为NULL,这样在下次使用的时候判断是否为NULL就可以了
      

  5.   

    你也可以不赋NULL,那么你在用这个句柄操作的时候,GetLastError,能够得到无效句柄的错误。
      

  6.   

    5楼的说得有道理,那看样子是没有函数可以判断HANDLE是否有效了!
      

  7.   


    如果Handle已经无效,除非是关闭或释放这个handle的API外,其它操作这个HANDLE的API都会返回错误的.例如你要ReadFile(),因为HANDLE已经关闭的话,ReadFile()肯定会出错的.这就是为什么很多API都有返回值,如果没必要的话,所有API都是VOID的了
      

  8.   

    但是不仅仅HANDLE无效会导致Readfile失败,其他还有很多导致失败的原因,这样还要通过GetLastError()来判断,这样实在是感觉有点麻烦,所以想先判断HANDLE是否有效
    另外有个新问题摆脱大家帮忙,就是如何判断COM1是否已经用CreateFile()打开了?
      

  9.   

    你每次CloseHandle()之后,马上将句柄赋为NULL...

    CloseHandle(handle);
    handle = NULL;
    配套.....这样的话就可以很方便的检验handle是否有效了......
      

  10.   

    句柄相当于一个指向指针的指针,指向指针的指针同样是指针,所以暂且认为它是一个指针,那么CreateFile相当于new 分配一个资源,让这个指针指到这块资源的首地址,那么当CloseHandle(handle)后等于是delete操作。此时handle的值还在,但是资源已被释放掉,那这个时候如果去访问这个句柄,就等于访问一个非法的内存资源。那么现在回到这个问题,如何判断句柄是否有效,就好比是回答如何判断指针是否有效。大家知道指针就是地址,如何判断地址是否有效呢?那就是判断这块地址上是否有有效数据了?那如何判断这个地址上有有效数据呢?微软提供了API,讲到这里问题基本就迎刃而解,希望楼主给分给我啊。答案另起一行答案:
    Tests a memory address to make sure it represents a currently active memory block that was allocated by the diagnostic version of new. 
    BOOL AfxIsMemoryBlock(
       const void* p,
       UINT nBytes,
       LONG* plRequestNumber = NULL 
    );
     
    或者:
    Tests any memory address to ensure that it is contained entirely within the program's memory space. 
    BOOL AfxIsValidAddress(
       const void* lp,
       UINT nBytes,
       BOOL bReadWrite = TRUE 
    ); 
     
    楼主用这两个API中的一个就看自己爱好了。回答完毕,等待楼主给分。
      

  11.   


    我这个例子怎么前后都是输出无效呢。int main(int argc, char *argv[])
    {
    HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    if (AfxIsValidAddress(hEvent, sizeof(hEvent), FALSE))
    {
    printf("有效\n");
    }
    else
    {
    printf("无效\n");
    } CloseHandle(hEvent);

    if (AfxIsValidAddress(hEvent, sizeof(hEvent), FALSE))
    {
    printf("有效\n");
    }
    else
    {
    printf("无效\n");
    }

        return 0;
    }
      

  12.   

    我想原因很简单,因为HANDLE根本不是new,所以一开始我就怀疑专业可能不行!
    new开辟的堆内存,是在虚拟地址空间里面的,而HANDLE似乎应该属于内核层的,所以根本不在一个地址空间内
      

  13.   

    让我来解释下HANDLE吧,用户进程空间存在一个句柄表,每个句柄占其中的一项,我们在程序中可以看到handle其实是一个类似0xffee的地址,这其实不是内存地址,其实是该句柄在句柄表中的索引而已。没个句柄表包含好几项信息,当然会包含一个指向内核空间的数据结构。这样Windows就保证了我们不能直接操作内核数据。只能调用API。