преобразование массива char в LPCTSTR в c - PullRequest
11 голосов
/ 10 июня 2009

Кто-нибудь знает, как преобразовать массив символов в LPCTSTR в c?

Edit:

Для получения дополнительной информации мне нужно добавить целое число в строку, а затем преобразовать эту строку в LPCTSTR для первого параметра функции Windows CreateFile ().

Это жестко закодированный пример, который я сейчас использую, но мне нужно иметь возможность передавать любое число для использования в качестве номера порта.

CreateFile(_T("\\\\.\\COM11")... //hardcoded for com port 11

и вот несколько вещей, которые я попробовал, и которые, я полагаю, включают следующие предложения для следующих 2 ответов этого поста. К сожалению, они не работают. Если бы кто-то мог указать на то, что я сделал неправильно, и, возможно, решить мою проблему, я был бы признателен.

Все эти примеры предполагают, что portNum - это int, которому уже присвоено допустимое значение

1

char portName[12] = { 0 };

sprintf_s( portName, sizeof( portName ), "\\\\.\\COM%i", portNum );

CreateFile(portName...

Я также попробовал # 1 с делом LPCSTR за то, что он стоит ...

2

LPCSTR SomeFunction(LPCSTR aString) {
    return aString;
}

main() {

char portName[12] = { 0 };
sprintf_s( portName, sizeof( portName ), "\\\\.\\COM%i", portNum );

LPCSTR lpPortName = SomeFunction(portName);

CreateFile(lpPortName...

3

const char * portName = "";
sprintf_s( portName, sizeof( portName ), "\\\\.\\COM%i", portNum );

LPCSTR lpPortName = portName;

CreateFile(lpPortName...

Ответы [ 8 ]

34 голосов
/ 10 июня 2009

Вы можете неявно преобразовать массив символов в 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, ...);
3 голосов
/ 10 июня 2009

В каком формате ваш массив символов?

Это const char[] или неконстантно?

LPCSTR - это просто (несколько) запутанное название Microsoft для «Long Pointer to Constant String».

LPCSTR bar = "hello";
const char *foo = bar;

const char *evil = "hello";
LPCSTR sauron = evil;

Если вам нужно получить неконстантную версию, вы либо отбрасываете константу, либо копируете в новый массив. Я бы предпочел последнее. Переменные часто бывают постоянными по какой-то причине, и их изменение почти всегда является плохой практикой.

2 голосов
/ 29 сентября 2011

попробуй вот так .........

TCHAR *pcCommPort = TEXT("COM1");
HANDLE h = CreateFile(pcCommPort,other arguments);
1 голос
/ 12 июня 2009

У вас есть строковые функции для TCHAR. Вы можете использовать, например, stprintf_s, принимающий TCHAR. Таким образом, вы делаете код «независимым» от юникода или многобайтового набора символов.

Ваш код (вариант 1) становится:

TCHAR portName[12] = { 0 };

stprintf_s( portName, sizeof( portName ) / sizeof(TCHAR), _T("\\\\.\\COM%i"), portNum );

CreateFile(portName...
0 голосов
/ 07 апреля 2017

Это старый классический вопрос. Я использую его в UNICODE.

char *pChar = "My Caption of My application";
    WCHAR wsz[512];
    swprintf(wsz, L"%S", pChar);
    SetWindowText(hWnd,         // ウィンドウまたはコントロールのハンドル
        wsz   // タイトルまたはテキスト
    );
0 голосов
/ 22 января 2015
char* filename;
LPCTSTR ime = CA2W(filename);

Это макрос преобразования строк, который работает на моем VS12

0 голосов
/ 13 декабря 2013

Я не уверен, что вы что-то выяснили в конце, но у меня возникла та же проблема, и мне помогло следующее:

int  comPortNum = 5;
char comPortName[32];
sprintf((LPTSTR)comPortName, TEXT("\\\\.\\COM%d"), comPortNum);
HANDLE h = CreateFile(comPortName,other arguments);
0 голосов
/ 12 июня 2009

"Кто-нибудь знает, как преобразовать массив символов в LPCSTR в c?"

Тебе вообще ничего не нужно делать. Он автоматически преобразуется в этот тип (кроме инициализаторов и sizeof).

"CreateFile (PortName ..."

Возможно, вам следует сообщить нам сообщение об ошибке, которое VC ++ выдает вам во время компиляции?

Возможно, вам также следует сообщить нам, какое сообщение об ошибке выдает VC ++, когда версия Адама Розенфилда whcar_t у вас не работает?

...