Russian Qt Forum

Qt => Общие вопросы => Тема начата: gueRRero от Март 21, 2009, 11:05



Название: Преобразование char_t* в QString*
Отправлено: gueRRero от Март 21, 2009, 11:05
Проблема такая: есть сторонняя библиотека, одна из функций которой возвращает char_t*. Это значение необходимо добавить в QListWidget, а он не работает с char_t*. Подскажите, каким образом это можно обойти. Желательно без приведения типов.


Название: Re: Преобразование char_t* в QString*
Отправлено: BRE от Март 21, 2009, 12:15
Проблема такая: есть сторонняя библиотека, одна из функций которой возвращает char_t*. Это значение необходимо добавить в QListWidget, а он не работает с char_t*. Подскажите, каким образом это можно обойти. Желательно без приведения типов.
Главное с самого начала понять как Qt работает со строками.
В Qt (QString) все строки хранятся в кодировке UNICODE. Сторонние библиотеки могут возвращать строки (char_t*) в других кодировках (CP1251, CP866, KOI8-R, UTF8 и еще огромная куча всяких других).
Для того, что бы использовать такие строки в Qt нужно их конвертировать в UNICODE и соответственно, если необходимо передать в функции сторонней библиотеки строку из QString, ее нужно конвертировать из UNICODE в ту кодировку которую ожидает эта библиотека.
Конвертацией строк занимается объект класса QTextCodec. Пример работы (пусть сторонняя библиотека работает в кодировке CP1251):
Код
C++ (Qt)
// Получаем необходимый кодек
QTextCodec *codec = QTextCodec::codecForName( "Windows-1251" );
 
// Получение строки QString из char*
const char *fromStr;
QString str = codec->toUnicode( fromStr );
 
// Получение строки char* из QString
QString fromStr;
const char *str = codec->fromUnicode( fromStr ).constData();
 

В твоем случае, я бы предложил сделать класс-враппер для твоей сторонней библиотеки, внутри которого и будет происходить конвертация строк. А для использования внутри программы этот класс предлагал аналоги функций из библиотеки с использованием QString:
Код
C++ (Qt)
class SuperLib
{
public:
    SuperLib();
 
    QString func1();
    void     func2( const QString &par1, )
 
private:
    QTextCodec *m_codec;
}
 
SuperLib::SuperLib()
{
   ....
   m_codec = QTextCodec::codecForName( "Windows-1251" );
}
 
QString SuperLib::func1()
{
   const char *str = mega_function_from_super_lib(.....);
   return codec->toUnicode( str );
}
 
void SuperLib::func2( const QString &str )
{
   const char *ptr = codec->fromUnicode().fromUnicode( str );
   mega_function_from_super_lib( ptr );
}
 

Как видишь, если все делать правильно, а не пользоваться костылями, тут не то что без приведения типов не обойтись, а и код специальный писать нужно.  ;)


Название: Re: Преобразование char_t* в QString*
Отправлено: gueRRero от Март 21, 2009, 12:40
Спасибо за консультацию. Попробовал сделать, как вы предложили, но компилятор ругается. Говорит: error: no matching function for call to `QTextCodec::toUnicode(const char_t*)'. Я так понял, предложенное будет работать для char* в разных кодировках. Но проблема именно в том, что Qt не хочет работать с char_t*.
З.Ы. Возвращаемое значение и так в Unicode.


Название: Re: Преобразование char_t* в QString*
Отправлено: BRE от Март 21, 2009, 12:50
Спасибо за консультацию. Попробовал сделать, как вы предложили, но компилятор ругается. Говорит: error: no matching function for call to `QTextCodec::toUnicode(const char_t*)'. Я так понял, предложенное будет работать для char* в разных кодировках. Но проблема именно в том, что Qt не хочет работать с char_t*.
З.Ы. Возвращаемое значение и так в Unicode.
А здесь приведение типов нужно использовать, как не крути.


Название: Re: Преобразование char_t* в QString*
Отправлено: gueRRero от Март 21, 2009, 12:54
Жаль, конечно, что никак не обойти... Но огромное спасибо за советы.


Название: Re: Преобразование char_t* в QString*
Отправлено: BRE от Март 21, 2009, 12:57
Жаль, конечно, что никак не обойти... Но огромное спасибо за советы.
А почему не хочется использовать приведение типов?
Тем более, что в библиотеке char_t скорее всего определен как:
Код
C++ (Qt)
#ifdef ....
typedef char char_t;
#else
typedef wchar char_t;
#endif
 


Название: Re: Преобразование char_t* в QString*
Отправлено: gueRRero от Март 21, 2009, 21:51
Вы совершенно правы:
Код:
#ifdef UNICODE
typedef wchar_t char_t;
#else
typedef char char_t;
#endif
И именно поэтому приведение типов нежелательно, т.к. если UNICODE не объявлен, то все хорошо, а вот если объявлен... wchar_t и char даже по размеру разные. Приводя типы можно что-нибудь потерять... Поправьте, если я не прав.


Название: Re: Преобразование char_t* в QString*
Отправлено: BRE от Март 21, 2009, 22:48
И именно поэтому приведение типов нежелательно, т.к. если UNICODE не объявлен, то все хорошо, а вот если объявлен... wchar_t и char даже по размеру разные. Приводя типы можно что-нибудь потерять... Поправьте, если я не прав.
Мне кажеться, что проблем быть не должно. Ты передаешь адрес массива с завершаюшим 0, дальше тот кто будет эту строку получать (Qt) должен знать что это обычная строка или UNICODE-строка.