Явный вызов WINAPI ReadFile () - PullRequest
       3

Явный вызов WINAPI ReadFile ()

1 голос
/ 27 августа 2011

Я работаю с устройством Garmin GPS и пытаюсь извлечь информацию о широте, долготе и т. Д. Через USB.Я работал в SDK и дошел до того, что смог вытащить эту информацию, поэтому сейчас я работаю над внедрением этого кода в систему, в которой я работаю.

Этот код помещается вкласс: CGarminUSBEngine, который наследуется от CASCIIEngine

Я извлекаю эту информацию из устройства, используя код

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

Моя проблема заключается в том, что CASCIIEngine, от которого наследуется CGarminUSBEngine, имеет функцию

BOOL ReadFile(void)

и когда я пытаюсь вызвать ReadFile () с 5 параметрами для чтения с моего USB-устройства, я получаю сообщение об ошибке компилятора, говорящее «CASCIIEngine :: Readfile»: функция не принимает 5 аргументов »

Мне еще предстоит выяснить, как явно вызвать WINAPI-версию этой функции ReadFile () или даже почему это необходимо.Мне кажется, что компилятор должен знать, что ReadFile перегружен, и я пытаюсь вызвать версию WINAPI, а не версию CASCIIEngine.

В основном я хотел бы знать, как явно вызывать версию WINAPI, а во-вторых, я бы хотел точно знать, почему это необходимо.Возможно, что-то простое мне просто не хватает, что было бы неприятно.Я ценю любую помощь.

1 Ответ

7 голосов
/ 27 августа 2011

Вы получаете сообщение об ошибке, потому что компилятор разрешает вызов CASCIIEngine::Readfile() вместо глобальной функции ReadFile(), предоставляемой Windows API .

Очевидно, числоаргументов не совпадают, поэтому компилятор жалуется.

Чтобы указать компилятору ссылаться на глобальную функцию ReadFile(), используйте оператор разрешения области действия ::.

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

† Точные правила, определяющие, какая функция разрешается, подробно изложены в стандарте 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, начиная с самого внутреннего включающего класса), или
  • , если 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) и не используется для формирования указателяto (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

Таким образом, глобальная функция даже не рассматривалась для разрешения перегрузки, потому что она не была функцией-членом.

Когда вы используете оператор разрешения области действия :: вКак указано выше, оно становится квалифицированным именем, относящимся к имени в глобальном пространстве имен, и, следовательно, вышеуказанные правила не применяются.

...