显式调用WINAPI ReadFile()

1 c++ winapi readfile

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

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

我使用代码从设备中提取此信息

ReadFile (gHandle,
  TheNewBuffer,
  MAX_BUFFER_SIZE,
  &theBytesReturned,
  NULL);
Run Code Online (Sandbox Code Playgroud)

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

BOOL ReadFile(void)
Run Code Online (Sandbox Code Playgroud)

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

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

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

In *_*ico 7

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

显然参数的数量不匹配,所以编译器抱怨.

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

   ::ReadFile (gHandle, TheNewBuffer, MAX_BUFFER_SIZE, &theBytesReturned, NULL);
// ^^---- Note `::`
Run Code Online (Sandbox Code Playgroud)

†确定哪个函数已解决的确切规则在C++标准中有详细说明.您的情况的相关条款如下:

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

1.在3.4.1所列的所有情况下,在每个类别中列出的顺序中搜索范围; 一旦找到名称的声明,名称查找就会结束. 如果没有找到声明,该程序就是格式错误.

...

8.在类的成员函数(9.3)的定义中使用的名称 X之后的功能的declarator-id应以下列方式之一来宣称:

  • 在用于使用它的块中或在封闭块(6.3)中使用之前,或
  • 应是班级成员X或是X(10.2)基类的成员 ,或
  • 如果X是一个嵌套类类Y(9.7),应的成员 Y,或应当是基类中的一个成员Y(此查找适用依次Y的封闭类,从最里面的外围类),或
  • if X是本地类(9.8)或者是本地类的嵌套类,在包含类定义的X块中定义类之前X,或者
  • 如果X是命名空间中的一员N,或者是一个嵌套类的类是其成员的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,如果名称查找(3.4.1)在解析名称id-expression类的非静态无类型成员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
Run Code Online (Sandbox Code Playgroud)

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

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