Отправлено: 30.07.12 14:40. Заголовок: Адаптация кода C++ в КаВо
Добрый день!
Найдётся ли специалист, который сможет мне помочь адаптировать код C++ в CA-Visual Objects? Общие представления у меня есть, но некоторые вещи у меня не получаются.
HANDLE OpenReader(TCHAR tszNewIPAddress[32], WORD wPort) {
Что значит TCHAR tszNewIPAddress[32], почему нельзя написать просто TCHAR tszNewIPAddress ? Что означают цифры 32? Я так подозреваю, что это длина в Unicode, а в ANSI это, наверное, будет 16... А без указания длины можно?
TCHAR tszNewIPAddress[32] - это объявление массива в качестве параметра функции из элементов TCHAR длиной 32 элемента. В С/С++ при передаче имени массива в качестве аргумента он преобразуется в указатель на свой первый элемент. Поэтому данное объявление функции эквивалентно следующему:
HANDLE OpenReader(TCHAR *tszNewIPAddress, WORD wPort);
Почему был выбран первый вид объявления параметра функции в виде массива, а не указателя? Это было сделано для самодокументирования функции, чтобы пользователь знал, какой тип массива, то есть сколько элементов у этого массива должно быть, когда его имя передается в функцию в качестве аргумента. То есть для читающего это объявление функции предоставляется дополнительная информация о том, какой размер должен иметь массив, передаваемый в функцию. Сам размер массива в байтах определяется как 32 * sizeof( TCHAR ). Если вы имете дело с ASCII кодировкой, то TCHAR будет занимать один байт, если с UNICODE, то два байта.
Просто смотрю текст (примера): (Main) hReader = OpenReader(TEXT("157.235.88.44"), 3000); // Это строка
но, в функции - это массив HANDLE OpenReader(TCHAR tszNewIPAddress[32], WORD wPort)
при этом, в функции OpenReader тут же передаётся (без изменений) в функцию ConfigureTCPIP: IF(ConfigureTCPIP(hReader, tszNewIPAddress, wPort))
где, это вроде как указатель на строку: bool ConfigureTCPIP(HANDLE hReader, TCHAR *ptszIPAddress, WORD wPort)
Это особенности синтаксиса Си, или я чего-то не понимаю?
TEXT("157.235.88.44") - это строковый литерал. В С/С++ они хранятся в памяти как массивы символов, содержащих завершающий нулевой символ. Как я уже написал выше, при передаче имени массива в качестве аргумента, он преобразуется в указатель на свой первый элемент. Поэтому объявления параметров, которые вызывают у вас вопросы, эквивалентны. То есть объявление параметра в виде TCHAR tszNewIPAddress[32] эквивалентно объявлению его в виде TCHAR *ptszIPAddress. Просто первое объявление более информативно, так как подсказывает пользователю функции, что передаваемый массив по крайней мере должен быть не меньше указанной размерности.
Отправлено: 30.07.12 17:20. Заголовок: Всем большое спасибо..
Всем большое спасибо!!! Извините, что долго не отвечал - писал программку и тестировал. Sergey Spirin навёл меня на правильную мысль фразой "по ссылке и по значению" И я начал писать программу... Как я и догадывался, RFID_GetCommandStatusText возвращала Unicode и я воспользовался наводкой на WideCharToMultiByte() (Только в лоб её использовать не получилось, пришлось подстелить :))
А когда вернулся, оказалось, что Сыроежка - просто разжевал для идиотов.
Ребята, большое Вам спасибо !!!! Поставил Вам плюсы :)) Удачи всем!!!
Просто смотрю текст (примера): (Main) hReader = OpenReader(TEXT("157.235.88.44"), 3000); // Это строка
но, в функции - это массив HANDLE OpenReader(TCHAR tszNewIPAddress[32], WORD wPort)
при этом, в функции OpenReader тут же передаётся (без изменений) в функцию ConfigureTCPIP: IF(ConfigureTCPIP(hReader, tszNewIPAddress, wPort))
где, это вроде как указатель на строку: bool ConfigureTCPIP(HANDLE hReader, TCHAR *ptszIPAddress, WORD wPort)
Это особенности синтаксиса Си, или я чего-то не понимаю?
Я сразу же не обратил внимание, но использование функции OpenReader из примера не согласуется с ее объявлением. Что я имею в виду? В вашем примере функция используется как
То есть в качестве первого параметра передается строковый литерал. Согласно стандарту языков С/С++ строковые литералы изменять нельзя. Поэтому их нельзя передавать в качестве аргумента тем функциям, которые принимают неконстантный указатель или массив. Функция OpenReader объявлена таким образом, что ее первый параметр не является константным
HANDLE OpenReader(TCHAR tszNewIPAddress[32], WORD wPort);
Это означает, что функция вправе изменить значения массива, которые передаются по указателю (как уже упоминалось ранее, при передаче массива в качестве аргумента, он преобразуется в указатель на его первый элемент). А это может привести к аварийному завершению программы. То есть можно было бы передавать строковый литерал, если бы объявление функции имело вид:
HANDLE OpenReader(const TCHAR tszNewIPAddress[32], WORD wPort);
то есть если бы первый параметр имел квалификатор const. Это было бы соглашением между функцией и ее пользователем, что значения массива менятся не будут. Но такого квалификатора нет у исходного объявления функции, а потому напрямую передавать ей строковый литерал в качестве значения первого параметра будет некорректным. Нужно будет в коде пользователя сначала объявить массив, инициализировав его строковым литералом, а уж затем этот массив передавать данной функции в качестве аргумента. Так будет корректнее.
HANDLE OpenReader(const TCHAR tszNewIPAddress[32], WORD wPort);
то есть если бы первый параметр имел квалификатор const. Это было бы соглашением между функцией и ее пользователем, что значения массива менятся не будут. Но такого квалификатора нет у исходного объявления функции, а потому напрямую передавать ей строковый литерал в качестве значения первого параметра будет некорректным. Нужно будет в коде пользователя сначала объявить массив, инициализировав его строковым литералом, а уж затем этот массив передавать данной функции в качестве аргумента. Так будет корректнее.
Именно так я и сделал. И код у меня не проходил именно по той причине, что Вы указали. И хотя я это сделал ещё вчера - Ваше сегодняшнее дополнение очень важно для тех, кто захочет ознакомиться с этой темой!
Большое Вам спасибо!
Думаю, когда всё получиться, сделать маленькую запись об этом в своём блоге. К сожалению, Сыроежка, в Вашем профиле нет Ваших ФИО, поэтому дам ссылку только на НИК. У меня в профиле тоже нет данных - не даёт изменить... Видимо глюк движка.
P.S.: Глюк разрешился: движок не совсем корректно работает с IE8 Сейчас зашёл под Mozilla Firefox - и сразу удалось скорректировать данные в профиле. В общем, если что - мои данные в профиле.
Все даты в формате GMT
3 час. Хитов сегодня: 21
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет