显式调用WINAPI ReadFile()

时间:2011-08-26 20:58:25

标签: c++ winapi readfile

我正在使用Garmin GPS设备,并尝试通过USB提取与纬度,经度等有关的信息。我在SDK中工作,并且我已经把这个信息拉出来了,所以现在我正在努力将这些代码滚动到我正在使用的系统中。

此代码放在一个类中:CGarminUSBEngine继承自CASCIIEngine

我使用代码

从设备中提取此信息
ReadFile (gHandle,
  TheNewBuffer,
  MAX_BUFFER_SIZE,
  &theBytesReturned,
  NULL);

我的问题是CGarminUSBEngine继承的CASCIIEngine具有该功能

BOOL ReadFile(void)

当我尝试用5个参数调用ReadFile()从我的USB设备读取时,我收到编译错误,说“'CASCIIEngine :: Readfile':函数不带5个参数”

我还没弄明白如何显式调用这个ReadFile()函数的WINAPI版本,或者甚至为什么需要它。在我看来编译器应该知道ReadFile是重载的,我试图调用WINAPI版本,而不是CASCIIEngine版本。

主要是我想知道如何明确调用WINAPI版本,其次我想知道为什么这是必要的。也许它很简单,我只是想念,这将是令人沮丧的。我赞美任何帮助。

1 个答案:

答案 0 :(得分:7)

您收到错误是因为编译器正在解析对CASCIIEngine::Readfile()的调用,而不是Windows API 提供的全局ReadFile()函数。

显然,参数的数量不匹配,因此编译器会抱怨。

要告诉编译器引用全局ReadFile()函数,请使用::范围解析运算符。

   ::ReadFile (gHandle, TheNewBuffer, MAX_BUFFER_SIZE, &theBytesReturned, NULL);
// ^^---- Note `::`

†确定哪个功能得到解决的确切规则在C ++标准中有详细说明。您的情况的相关条款如下:

  

3.4.1非限定名称查找[basic.lookup.unqual]

     

1。在3.4.1中列出的所有情况下,搜索范围为a   按各自类别列出的顺序进行声明;   一旦找到名称的声明,名称查找就会结束。   如果没有找到声明,该程序就会形成错误。

     

...

     

8. 在类的成员函数(9.3)的定义中使用的名称   函数X之后的declarator-id应声明为一个   有以下几种方式:

     
      
  • 在用于使用它的块中或封闭之前   块(6.3)或
  •   
  • 应该是类X的成员或者是基类的成员   X(10.2)或
  •   
  • 如果X是类Y(9.7)的嵌套类,则应为   Y,或者应该是Y基类的成员(此查找适用   反过来到Y的封闭类,从最里面开始   封闭类)或
  •   
  • 如果X是本地类(9.8)或是本地的嵌套类   class,在包含该块的块中定义类X之前   类X
  • 的定义   
  • 如果X是命名空间N的成员,或者是a的嵌套类   作为N成员的类,或者是本地类或嵌套类   在N成员之前的一个函数的本地类中   成员函数定义,在命名空间N中或在N之一中   封闭名称空间。
  •   
     

...

     

9.3.1非静态成员函数[class.mfct.nonstatic]

     

2. id-expression(5.1)不属于班级成员时   访问语法(5.2.5)并且不用于形成指向成员的指针(5.3.1)   用于类X或类的非静态成员函数体中   在mem-initializer中用于类X的构造函数, if   名称查找(3.4.1)将id-expression中的名称解析为a   类X的非静态非类型成员或X的基类,   id-expression转换为类成员访问表达式   (5.2.5)使用(*this)(9.3.2)作为左侧的后缀表达式   .运算符。成员名称然后引用成员   调用函数的对象...

根据3.4.1 / 1和3.4.1 / 8,ReadFile()类中CASCIIEngine的声明首先(第二个要点)在ReadFile()之前找到全局命名空间(最后一个项目符号点),因此名称查找解析为成员函数。

这意味着您班上对ReadFile()的电话实际上已经解决了这个问题:

(*this).ReadFile(gHandle, TheNewBuffer, MAX_BUFFER_SIZE,
    &theBytesReturned, NULL); // Per 9.3.1/2

因此,全局函数甚至没有考虑重载解析,因为它不是成员函数。

当您以上面使用的方式使用::范围解析运算符时,它将成为引用全局命名空间中的名称的限定名称,因此上述规则不适用。