【问题标题】:Explicitly calling WINAPI ReadFile()显式调用 WINAPI ReadFile()
【发布时间】:2011-11-04 20:18:57
【问题描述】:

我正在使用 Garmin GPS 设备,并试图通过 USB 从中提取与纬度、经度等相关的信息。我在 SDK 中工作并达到了可以提取这些信息的地步,所以现在我正在努力将此代码滚动到我正在工作的系统中。

这段代码被放置在一个类中:CGarminUSBEngine,它继承自 CASCIIEngine

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

ReadFile (gHandle,
  TheNewBuffer,
  MAX_BUFFER_SIZE,
  &theBytesReturned,
  NULL);

我的问题是CGarminUSBEngine继承的CASCIIEngine有这个功能

BOOL ReadFile(void)

当我尝试使用 5 个参数调用 ReadFile() 以从我的 USB 设备读取时,我收到一个编译器错误,提示“'CASCIIEngine::Readfile' : function does not take 5 arguments”

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

主要是我想知道如何显式调用WINAPI版本,其次我想知道为什么这是必要的。也许我只是想念一些简单的东西,这会令人沮丧。我感谢任何帮助。

【问题讨论】:

    标签: c++ winapi readfile


    【解决方案1】:

    您收到错误是因为编译器正在解析对 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 中列出的所有情况下,都会在范围内搜索 按各个类别中列出的顺序声明; 一旦找到名称的声明,名称查找就会结束。 如果没有找到声明,则程序格式错误。

    ...

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

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

    ...

    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,CASCIIEngine 类中 ReadFile() 的声明首先被发现(第二个要点),在全局命名空间中的 ReadFile() 之前(最后一个要点) ),因此名称查找解析为成员函数。

    这意味着您在课堂上对ReadFile() 的调用实际上正在解析为:

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

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

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

    【讨论】:

    • 天哪。我知道这会非常简单,但我忘记了我的基本 C++。我尝试了 __super:: WINAPI:: 等...如此接近但到目前为止。非常感谢您解决这个问题,效果很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 2015-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    相关资源
    最近更新 更多