Member 12557572 Ответов: 1

Проблема с типом байта в дружественном имени последовательного порта в C++ с использованием набора символов unicode


Я использую SetupDiGetDeviceRegistryProperty из setupapi в Visual Studio. Если я использую набор из нескольких сочетаний клавиш, указатель байт (Byte* friendlyname используется) дает правильный friendlyname используется. Однако, когда я компилирую его с помощью набора символов Unicode, возвращаемое friendlyName имеет нулевой символ за каждым значением в массиве байтов.

Вот фрагмент кода:

SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, nullptr, nullptr, 0, &reqSize);
BYTE* friendlyName = new BYTE[300]; //(reqSize > 1) ? reqSize : 1];

if (!SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, nullptr, friendlyName, sizeof(friendlyName) * reqSize, nullptr))
{
// устройство не имеет этого набора свойств
memset(friendlyName, 0, reqSize > 1 ? reqSize : 1);
}

Что я уже пробовал:

Я попытался изменить массив байтов (unsigned char) на байт с теми же результатами. Если я попытаюсь изменить его на char, компилятор не будет работать.

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

1 Ответов

Рейтинг:
11

Rick York

Такое поведение является преднамеренным, потому что такова природа символов Юникода. Более низкая партия, ниже значения 256, имеет ноль после них, потому что они (как правило) являются 16-битным значением, поэтому MSB будет равен нулю.

Я бы использовал макросы TCHAR, если вы собираетесь компилировать в обоих режимах. Вот вам пример:

const int BufferSize = 299;
TCHAR friendlyName[BufferSize+1] = { 0 };

if( ! SetupDiGetDeviceRegistryProperty( hDeviceInfo, &devInfoData,
          SPDRP_FRIENDLYNAME, nullptr,
          friendlyName, BufferSize, nullptr ) )
{
    TRACE( _T( "device does not have this property set\n" ) );
}


Rick York

примечание - Я не уверен, что это правильный способ использовать SetDiGetDeviceRegistryProperty. Я просто предположил, основываясь на вашем коде.

Member 12557572

Рик, пытался использовать ТЧАР. Ошибки компиляции возвращают "не удается преобразовать аргумент из TCHAR в PBYTE". Есть ли что-то, что мне нужно настроить в includes или properties, что позволяет мне использовать TCHAR?

Rick York

Вы должны включить tchar.h и определить _UNICODE и/или UNICODE в настройках препроцессора вашего проекта.

Member 12557572

Я делал все это и все равно получал ошибку компиляции. Но потом я бросил friendlyName как PBYTE. Когда я это сделал, он работал так, как и ожидалось, без нулевых символов после каждого "допустимого" символа. Спасибо за вашу помощь.

Dean Roddey

Приведите его к a (BYTE*), когда вы передаете его в API, который ожидает массив байтов. После того, как он будет заполнен, и вы посмотрите на него через указатель TCHAR, тогда он будет правильным. Или сохраните его в виде массива типа BYTE*, а затем приведите его к TCHAR, чтобы посмотреть на него позже, так или иначе.

константный файле TCHAR* реальное имя = оператора reinterpret_cast&ЛТ;строительства файле TCHAR*&ГТ;(friendlyname используется);

realName затем будет смотреть на буфер через правильный тип и должен работать правильно.

Конечно, обязательно очистите буфер в какой - то момент.