我正在使用 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 版本,其次我想确切地知道为什么需要这样做。也许它只是缺少一些简单的东西,这会令人沮丧。我感谢任何帮助。
最佳答案
您收到错误是因为编译器正在解析对 CASCIIEngine::Readfile()
的调用,而不是 Windows API 提供的全局 ReadFile()
函数†.
显然参数的数量不匹配,所以编译器会报错。
要告诉编译器引用全局 ReadFile()
函数,请使用 ::
范围解析运算符。
::ReadFile (gHandle, TheNewBuffer, MAX_BUFFER_SIZE, &theBytesReturned, NULL);
// ^^---- Note `::`
† 确定解析哪个函数的确切规则在 C++ 标准中有非常详细的规定。针对您的情况,相关条款如下:
3.4.1 Unqualified name lookup [basic.lookup.unqual]
1. In all the cases listed in 3.4.1, the scopes are searched for a declaration in the order listed in each of the respective categories; name lookup ends as soon as a declaration is found for the name. If no declaration is found, the program is ill-formed.
...
8. A name used in the definition of a member function (9.3) of class
X
following the function’sdeclarator-id
shall be declared in one of the following ways:
- before its use in the block in which it is used or in an enclosing block (6.3), or
- shall be a member of class
X
or be a member of a base class ofX
(10.2), or- if
X
is a nested class of classY
(9.7), shall be a member ofY
, or shall be a member of a base class ofY
(this lookup applies in turn toY
’s enclosing classes, starting with the innermost enclosing class), or- if
X
is a local class (9.8) or is a nested class of a local class, before the definition of classX
in a block enclosing the definition of classX
, or- if
X
is a member of namespaceN
, or is a nested class of a class that is a member ofN
, or is a local class or a nested class within a local class of a function that is a member ofN
, before the member function definition, in namespaceN
or in one ofN
’s enclosing namespaces....
9.3.1 Nonstatic member functions [class.mfct.nonstatic]
2. When an
id-expression
(5.1) that is not part of a class member access syntax (5.2.5) and not used to form a pointer to member (5.3.1) is used in the body of a nonstatic member function of classX
or used in themem-initializer
for a constructor of classX
, if name lookup (3.4.1) resolves the name in theid-expression
to a nonstatic nontype member of classX
or of a base class ofX
, theid-expression
is transformed into a class member access expression (5.2.5) using(*this)
(9.3.2) as the postfix-expression to the left of the.
operator. The member name then refers to the member of the object for which the function is called ...
根据 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++ - 显式调用 WINAPI ReadFile(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7210496/