Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Indy 10, BCB6 и UTF-8


Автор: ilyuha 5.6.2013, 18:30
Приветствую, уважаемые комрады smile
Ситуация в следующем. Мне необходимо в давно поддерживаемый  проект добавить функции приема и отправки E-mail(что уже реализовано).
Полученные и отпроавленные сообщения пишутся в базу, куда тема и тело сообщения должны писаться в utf-8.
При отправке проблем нет. А вот при приеме начинается самое интересное... Классы Indy не производят автоматичекой перекодировки текста в UTF-8, в неюникодных весиях IDE, коей является BCB6.
Перерыв весь гугл и доки  по Indy, я так не нашел способа, как можно преобразовать уже полученное сообщение в UTF-8.
Кодировка сообщение, после их получения, известна через свойство TIdMessage::CharSet.

Копал в сторону TIdCoder и TIdDecoder, но что-то безрезультатно... Может плохо искал? Помогите, плиз.

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

ЗЫ обновить билдер нет никакой возможности. 

Автор: borisbn 6.6.2013, 06:22
http://prantl.host.sk/iconv/

Автор: ilyuha 6.6.2013, 09:49
borisbn, Спасибо, но, как я понял, возможности подружить ее с билдером нет. А городить костыли через ShellExecute не хотелось бы...

Есть ли альтернативы? Ведь, полной функциональности, которая есть в iconv, и не надо. Достаточно, чтобы либа могла переводить в UTF-8 текст в кодировках, используемых для рпередачи мыла в восточной европе - cp1250-1259, КОИ8...

ЗЫ С носталгией вспоминаю QTextCodec...

Автор: borisbn 6.6.2013, 10:04
Лови (в аттаче). Делаешь
Цитата
implib.exe iconv.lib iconv.dll

подключаешь полученную lib в проект, кидаешь dll-ку к твоему exe-шнику.
Там же я положил мою обёрточку. В общем, там всё д.б. понятно

Автор: ilyuha 6.6.2013, 11:07
borisbn, Спасибо! Буду пробовать

Автор: ilyuha 6.6.2013, 19:30
borisbn, Вроде, все сделал верно, но что-то не конвертит... По порядку:
После implib.exe iconv.lib iconv.dll линкер ругался, что не может найти функции.
Это я решил, выполнив:
impdef.exe iconv.def iconv.dll
Далее, отредактировал iconv.def(имена функций там имели вид lib*, вместо _lib).
И сделал:
implib.exe iconv.lib iconv.def
implib выдал:
Цитата

Name: 'iconv' Ext: '.dll' Base: 0x00000000
Name: 'ICONV.DLL' Ext: '.dll' Base: 0x00000000

Это меня напрягло, да. Но прога собралась и функция iconv вызывается.
Далее, я немного приспособил код borisbn под свои нужды:
Код

CCodeConverter::CCodeConverter( const char *from, const char* to )
{
    converter = iconv_open( to, from );
}

AnsiString CCodeConverter::convert(const char* str, size_t length)
{
    AnsiString out;
    
    size_t in_size  = length;
    const char* in_ptr = str;

    char buffer[ BUFFER_LENGTH ];

    while ( in_size )
    {
        char*  out_ptr  = buffer;
        size_t out_size = BUFFER_LENGTH - 1;
        size_t size = iconv( converter, &in_ptr, &in_size, &out_ptr, &out_size );
        if ( size == (size_t)( -1 ) )
            break;
        buffer[ BUFFER_LENGTH - out_size - 1 ] = 0;
        out = out + buffer;
    }
    return out;
}

iconv всегда возвращает -1. errno == 0. converter валиден.
Используется этот код так:
Код

....
    CCodeConverter converter("KOI8-R", "UTF-8");
    return converter.convert(str.c_str(), str.Length());

Есть у кого какие-нибудь мысли? Хелп  smile 

Автор: ilyuha 7.6.2013, 09:07
Людиии, подкиньте хоть какую-нить идею smile 
Есть ли альтернатива iconv?

Автор: borisbn 7.6.2013, 09:28
ilyuha, последнее, чем могу помочь - это подкинуть iconv.lib (в аттаче) для билдера, который я сделал, и с которым у меня линкуется и работает (!!) твой код без единого изменения.

Автор: ilyuha 7.6.2013, 10:12
borisbn, Не работает :( Должно что-то отличаться, если у тебя работает, а у меня нет. Какая у тебя версия билдера?

Автор: borisbn 7.6.2013, 10:17
У меня 5-й. 
хммм... Ну, лови весь проект. Я не уверен, но м.б. он даже в твоём билдере откроется. Если заработает - ищи отличия в настройках проекта. Убедись, что у тебя в настройках проекта тип вызова по-умолчанию стоит __cdecl.

Автор: ilyuha 7.6.2013, 13:06
borisbn, Спасибо большое. Все было куда тривиальнее. Сделал размер буфера == length * 4 и  все заработало

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)