Вы можете неявно преобразовать массив символов в LPCSTR
без каких-либо приведений:
void SomeFunction(LPCSTR aString);
...
char myArray[] = "hello, world!";
SomeFunction(myArray);
LPCSTR
- это Windows typedef для длинного указателя на постоянную строку. В темные времена программирования на Win16 существовали разные типы указателей: около указателей и дальний указатели, иногда также известные как short и long указатели соответственно. Ближайшие указатели могут указывать только на сегмент памяти размером 64 КБ, определенный одним из регистров сегмента x86. Дальние указатели могут указывать на что угодно. В настоящее время в Win32 с виртуальной памятью нет необходимости в ближних указателях - все указатели длинные.
Итак, LPSTR
- это typedef для char *
или указатель на строку. LPCSTR
- это версия const
, т.е. это typedef для const char *
. В C массивы распадаются на указатели на свои первые элементы, поэтому char[]
распадается на char*
. Наконец, любой тип «указателя на T» (для любого типа T) может быть неявно преобразован в «указатель на const T». Таким образом, комбинируя эти три факта, мы видим, что мы можем неявно преобразовать char[]
в LPCSTR
.
В ответ на ваши изменения я догадываюсь, что вы компилируете приложение Unicode. Если вы внимательно посмотрите на документацию для CreateFile()
, вы заметите, что параметр имени файла на самом деле LPCTSTR
, а не LPCSTR
(обратите внимание на T
).
Практически для каждой функции Win32, которая принимает аргумент некоторого строкового типа (возможно, косвенно, то есть как элемент структуры, передаваемой в качестве параметра), на самом деле существует две версии этой функции: одна, которая принимает 8-битный ANSI строки, и тот, который принимает 16-битные строки широких символов. Чтобы получить действительные имена функций, вы добавляете A
или W
к имени функции. Итак, версия ANSI CreateFile()
называется CreateFileA()
, а версия с широкими символами - CreateFileW()
. В зависимости от того, выполняете ли вы компиляцию с включенным Юникодом (т.е. определен ли символ препроцессора _UNICODE
), символ CreateFile
равен #define
d или CreateFileA
или CreateFileW
, в зависимости от ситуации, и аналогично все остальные функции, которые имеют ANSI и широкоформатную версию.
В тех же строках тип TCHAR
имеет значение typedef
ed или char
или wchar_t
, в зависимости от того, включен ли Unicode, и LPCTSTR
имеет значение typedef
ed для указателя на const TCHAR
.
Таким образом, чтобы сделать ваш код корректным, вы должны заменить строки, которые вы используете, строками TCHAR
и использовать универсальную версию типа sprintf_s
, _stprintf_s
:
TCHAR portName[32];
_stprintf_s(portName, sizeof(portName)/sizeof(TCHAR), _T("\\\\.\\COM%d"), portNum);
CreateFile(portName, ...);
Кроме того, вы можете явно использовать ANSI или широкосимвольные версии всего:
// Use ANSI
char portName[32];
sprintf_s(portName, sizeof(portName), "\\\\.\\COM%d", portNum);
CreateFileA(portName, ...);
// Use wide-characters
wchar_t portName[32];
swprintf_s(portName, sizeof(portName)/sizeof(wchar_t), L"\\\\.\\COM%d", portNum);
CreateFileW(portName, ...);