Я пишу программу (ну … используя пример кода формы Tektronix) для проверки обмена сообщениями по сети с нашим анализатором спектра в нашей лаборатории.
Был предоставлен файл заголовка с именем «decl-32.h», и в примере кода приведена следующая строка вместе с ошибкой, которую он выдает:
ibwrt (GpibDevice, «SYSTem: ERRor: ALL?», strlen («SYSTem: ERRor: ALL?»));
«неверное преобразование из ‘const void *’ в ‘PVOID {aka void *}’ [-fpermissive]»
В заголовочном файле следующая строка кода выделена как ошибочная, наряду со следующей ошибкой:
extern int __stdcall ibwrt (int ud, PVOID buf, long cnt);
«Инициализация аргумента 2 для int ibwrt (int, PVOID, long int) ‘[-fpermissive]»
Проблема в том, что я незнаком с такими сложными определениями, использованиями и преобразованиями переменных.
Может ли кто-нибудь быть настолько любезным, чтобы дать мне совет? Я уверен, что это будет актуально для многих других, кто не знаком с такими типами переменных и преобразованиями и т. Д.
Заранее спасибо!
Второй параметр для ibwrt
является PVOID
который является typedef для void*
, В C ++ типы указателей неявно преобразуются в void*
, но, как и во всех других типах, преобразованию не разрешается удалять Qulifier. То есть преобразование из const char*
(который является строковым литералом типа decay to) в void*
незаконно Отсюда и ошибка.
В языке C, откуда исходит код, строковые литералы распадаются на char*
и ваша строка будет скомпилирована как есть. Причина историческая — ранние реализации C не имели const
ключевое слово.
Чтобы это исправить, вы можете разыграть const
прочь с const_cast
:
const char* s = "SYSTem:ERRor:ALL?";
ibwrt(GpibDevice, const_cast<char*>(s), strlen("SYSTem:ERRor:ALL?"));
Вы должны доверять функции, что она не будет пытаться изменить строковый литерал через указатель, который вы ей передали, иначе это вызовет неопределенное поведение. Похоже, безопасное предположение в этом случае (или, возможно, нет, параметр называется buf
, заметьте!), но если вы хотите быть уверенным, сделайте копию строки, которую @MikeSeymour показывает в своем ответе.
Проблема состоит в том, что строковые литералы являются неизменяемыми, и эта функция требуетconst
указатель на данные.
Если функция гарантированно не изменяет данные, а отсутствие const
это просто недосмотр, тогда вы можете привести к необходимому типу:
ibwrt(GpibDevice, const_cast<char*>("SYSTem:ERRor:ALL?"), strlen("SYSTem:ERRor:ALL?"));
Если это может изменить данные, то это даст неопределенное поведение, и вам понадобится локальная копия строки:
const char message[] = "SYSTem:ERRor:ALL?";
ibwrt(GpibDevice, message, strlen(message));
(Вы можете указать длину как менее очевидную, но, возможно, более эффективную sizeof message - 1
)