Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Локализация


Автор: drug007 22.12.2011, 08:28
Приложение состоит из нескольких слабосвязанных частей - гуй на кутэ, сетевая часть на буст.асио, логика без использования сторонних библиотек. Локализация в кутэ реализована изначально и меня устраивает, но в остальных частях придется реализовывать самому, так как мешать везде кутэ нельзя. На данный момент я тупо вынес в отдельные файлы декларации и определения используемых строковых констант и везде использую их. Но это менее удобно, чем кутэшная реализация, т.к. если добавляешь константу (а их добавлять полюбому придется) то нужно будет перекомпилировать значительную часть проекта. Использовать же для каждого файла отдельный файл со строковыми константами мне кажется довольно геморрным (хотя вроде так в яве реализовано?). 
Как можно лучше кроссплатформенно реализовать локализацию, не завязываясь на громоздкую стороннюю библиотеку/фреймворк (т.е. мелкую в принципе можно заюзать), но и не изобретая свой велосипед? Может ссылки кто подскажет, а то гугл выдает про виндовую локализацию.

Автор: boostcoder 22.12.2011, 08:54
юзаю sqlite с таблицей в виде:
Цитата

| lng | message_id | message |

lng - идентификатор языка.
message_id - целочисленные константы определенные в исходниках.
message - собственно, текст сообщения для указанного языка и идентификатора сообщения.

Автор: drug007 22.12.2011, 09:15
А как это в коде выглядит? Мне константы (айди в данном случае) кажутся не очень наглядными. Вот как у меня:
Код

//consts.h
class Strings {
public:
static const std::string SOME_ERROR_OCCURED;
}

//consts.cpp
const std::string Strings::SOME_ERROR_OCCURED = "some error occured";

//other.cpp
#include "consts.h"

int main() {
...
if (error) {
    std::cout << Strings::SOME_ERROR_OCCURED << std::endl;
    return -1;
}
...
return 0;
}

И меня смущают эти длинные имена констант, да и не очень наглядные они. С айди конечно покороче будет, но наглядность потеряется вообще имхо. Локализация у меня осуществляется на этапе линковки - выбором соответствующего .срр файла.
Динамическая локализация, конечно, получше будет, но особой заинтересованности в ней у меня нет. Но сделал я это на скорую руку, поэтому советуюсь.

Если нужно вывести какое-то значение в сообщении юзают boost.format:
Код

...
const std::string Strings::FILE_NOT_FOUND = "file %1% not found";
...
std::cout << boost::format(Strings::FILE_NOT_FOUND) % filename << std::endl;
...

Но смущает, что нужно знать о наличии аргументов у сообщения, чтобы правильно применить. Хотя может это и не страшно.

Автор: boostcoder 22.12.2011, 09:39
идентификаторы я забиваю в неймспейсы. обычно вложенные.
Код

namespace errors {
   namespace common { enum {
      config_file_not_found = 0,
      config_file_value = 1,
      limit_for_some_resource = 2
   };}
   namespace protocol { enum {
      procedure_id = 3,
      procedure_args = 4,
      ...
   };}
}


// usage

std::cout << singleton::messages->get(errors::common::config_file_not_found) << std::endl;
std::cout << singleton::messages->get(errors::protocol::procedure_args) << std::endl;


Цитата(drug007 @  22.12.2011,  09:15 Найти цитируемый пост)
Если нужно вывести какое-то значение в сообщении юзают boost.format ... смущает, что нужно знать о наличии аргументов у сообщения, чтобы правильно применить.

я так и делаю. не нашел "человеческого" решения.

Добавлено через 2 минуты и 14 секунд
при использовании enum class все выглядит более естественно.
Код

namespace errors {
   enum class common {
      config_file_not_found = 0,
      config_file_value = 1,
      limit_for_some_resource = 2
   };
   enum class protocol {
      procedure_id = 3,
      procedure_args = 4,
      ...
   };
}

Автор: bsa 22.12.2011, 12:25
drug007, ты можешь использовать средства того же Qt. Только объяви свои макросы и создай файл po с помощью gettext (linguist не поддерживает отличные от Qt'шных ключевые слова). Например, очень часто используют макрос _()... Таким образом:
Код
#define _(context,text...) qApp()->translate(context, text).toLocal8Bit()

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

Автор: boostcoder 22.12.2011, 12:32
Цитата(bsa @  22.12.2011,  12:25 Найти цитируемый пост)
средства того же Qt

кто бы сомневался smile 

Автор: bsa 22.12.2011, 12:43
Цитата(boostcoder @  22.12.2011,  13:32 Найти цитируемый пост)
кто бы сомневался

согласись, значительно более логично использовать то, что у тебя и так в проекте есть, чем добавлять еще что-то. Кстати, я бы никогда не догадался использовать реляционную БД для этих целей... Имхо, это сродни полету на вертолете в булочную напротив.

Автор: boostcoder 22.12.2011, 12:58
Цитата(bsa @  22.12.2011,  12:43 Найти цитируемый пост)
логично использовать то, что у тебя и так в проекте есть

использовать куте вообще не логично. просто выбирать особо не из чего.

Цитата(bsa @  22.12.2011,  12:43 Найти цитируемый пост)
я бы никогда не догадался использовать реляционную БД для этих целей

не удивительно.
интересно бы было посмотреть на то, как бы ты обновлял сотни тысяч клиентских программ объемом по 30мб, только из-за того что была исправлена опечатка в сообщении об ошибке.

Цитата(bsa @  22.12.2011,  12:43 Найти цитируемый пост)
это сродни полету на вертолете в булочную напротив.

ну да. ваши на такси в булочную не ездят.

Автор: bsa 22.12.2011, 13:34
Цитата(boostcoder @  22.12.2011,  13:58 Найти цитируемый пост)
интересно бы было посмотреть на то, как бы ты обновлял сотни тысяч клиентских программ объемом по 30мб, только из-за того что была исправлена опечатка в сообщении об ошибке.
это производится заменой одного файлика... В твоем случае тоже. Кстати, я впервые слышу об использовании БД в этих целях. Может не спроста никто этого не делает?

Скажи, зачем городить огород (неудобный к тому же), когда есть готовые решения? Тот же gettext, boost::localization, Qt... Тем более, что в проекте уже есть (и используется!) одно из перечисленных.

Автор: boostcoder 22.12.2011, 13:39
Цитата(bsa @  22.12.2011,  13:34 Найти цитируемый пост)
это производится заменой одного файлика

всего один вопрос: зачем создавать "этот" файлик, и потом "лечить" последствия его существования?

Цитата(bsa @  22.12.2011,  13:34 Найти цитируемый пост)
я впервые слышу об использовании БД в этих целях.

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

Добавлено через 14 минут и 25 секунд
Цитата(drug007 @  22.12.2011,  08:28 Найти цитируемый пост)
гуй на кутэ, сетевая часть на буст.асио

это в одном приложении?

Автор: bsa 22.12.2011, 14:00
Цитата(boostcoder @  22.12.2011,  14:39 Найти цитируемый пост)
всего один вопрос: зачем создавать "этот" файлик, и потом "лечить" последствия его существования?
sqlite не создает файлов?!?
Цитата(boostcoder @  22.12.2011,  14:39 Найти цитируемый пост)
раз не слышал - значит не в той отрасли работаешь.
я работаю с десктопами и embedded в потребительской сфере.
Цитата(boostcoder @  22.12.2011,  14:39 Найти цитируемый пост)
представь распределенные системы с сотнями тысяч узлов. ты бы стал по каждому чиху обновлять файлики?
тут речь не о web программировании. А о Qt приложении. Причем тут сотни тысяч узлов? А так же какое отношение sqlite имеет к этим узлам?
Если бы ТС написал: "делаю тонкий клиент к сетевой программе работающей удаленно и хочу, чтобы все было локализовано", то я бы может даже вместо sqlite postgres или oracle посоветовал. Но речь идет о другом (по крайней мере, я так понял ТС). И если делать локализацию через удаленную базу, то это усложнит запуск приложения, особенно, с неработающей сетью, а выбор sqlite выглядит вообще странным. Если ты предлагаешь через локальную базу, то чем она отличается от принятых методов локализации? Только тем, что изменения можно вносить путем загрузки только измененной записи БД? Сейчас такая экономия смысла особо не имеет. Никто не умрет, если придется грузить файл объемом 100 КБ (тем более, что это можно автоматизировать). А вот усложнение кода будет налицо.

drug007, рассмотри вариант с boost::localization. Возможно, он быстрее Qt будет в твоем случае.

Автор: boostcoder 22.12.2011, 14:05
Цитата(bsa @  22.12.2011,  14:00 Найти цитируемый пост)
sqlite не создает файлов?

его файлы не требуют замены, ибо есть http://phpclub.ru/mysql/doc/update.html.

Цитата(bsa @  22.12.2011,  14:00 Найти цитируемый пост)
!?

это лишнее.

Цитата(bsa @  22.12.2011,  14:00 Найти цитируемый пост)
я работаю с десктопами

я с десктопами не работаю. это в другом отделе.

Цитата(bsa @  22.12.2011,  14:00 Найти цитируемый пост)
речь не о web программировании

я не говорил о вебе.

Цитата(bsa @  22.12.2011,  14:00 Найти цитируемый пост)
А о Qt приложении

правда? т.е. если в приложении используется что-либо из куте, то оно становится кутеприложением? smile что за "мерка" такая?

Цитата(bsa @  22.12.2011,  14:00 Найти цитируемый пост)
Причем тут сотни тысяч узлов? А так же какое отношение sqlite имеет к этим узлам?

до свиданья.

Автор: boostcoder 22.12.2011, 14:20
Цитата(bsa @  22.12.2011,  14:00 Найти цитируемый пост)
Причем тут сотни тысяч узлов? А так же какое отношение sqlite имеет к этим узлам?

по правде сказать, я помню последние темы ТС, где он разрабатывал высокопроизводительный сервер. и на автомате, я предположил что куте у него - это клиенты.
и того: 1)высокопроизводительный сервер, 2)клиенты = сотни тысяч узлов которые нужно обновлять.

Автор: xvr 22.12.2011, 14:46
Базу имеет смысл применять (в данном случае) если она в проекте уже есть. То же касается и всего остального. Если же ничего 'остального' нет, то советую посмотреть в сторону отдельно стоящего http://www.gnu.org/software/gettext/(его уже тут упоминали), довольно легкая библиотека


Автор: newbee 22.12.2011, 14:48
Я одна не уловила связи между "сто пицот клиентов" и локальной СУБД?

Автор: boostcoder 22.12.2011, 14:56
Цитата(newbee @  22.12.2011,  14:48 Найти цитируемый пост)
Я одна

нее. на пару с bsa.

Автор: newbee 22.12.2011, 15:02
Цитата(boostcoder @  22.12.2011,  15:56 Найти цитируемый пост)
нее. на пару с bsa. 
Тогда будь добр, прекрати дерзить и раскрой нам глаза. Вот я не вижу разницы между сто тыщ замен файлов на клиентах и сто тыщ апдейтов в скулайте на клиентах.

Автор: kosmonaFFFt 22.12.2011, 20:24
Может быть подразумевалось централизованное обновление парка клиентов посредством отсылки SQL запроса? А ТС я бы порекомендовал все таки Qt или gettext.

Автор: drug007 23.12.2011, 07:08
Не ожидал такой бурной и оживленной дискуссии. =)
Спасибо за подсказки, буду смотреть в сторону gettext и boost::localization. Qt не буду применять по причине нежелания завязываться на нем. Сейчас на нем построен клиент и есть уже вопросы по быстродействию - старая виндовая реализация на дельфях в фоновом режиме практически не нагружает процессор, в то время как реализация на Qt жрет на той же машине минимум 5-6 процентов. Пока надеюсь, что проблема в том, что неправильно применяю, а не в самой Qt. В общем-то Qt меня устраивает, но применять не буду, чтобы иметь возможность отказаться.
Приложение у меня распределенное, но задачи удаленного обновления служебных сообщений, известных на этапе компиляции не стоит, что скомпилировали, тем юзер и пользуется - пока так, я не Шива и даже не Цезарь, все не успею. Поэтому интересует простая локальная локализация (простите за тавтологию).
Что касается использования БД - все имеет право на существование, в том числе и такое использование БД. Я вот планирую в будущем в приложении использовать in-memory BerklyDB (все-таки Калифорния это не только знойные спасатели с 5ым размером, Шварцнеггер и прочие Голливуды - молодцы ведь, правда? хотя может они тоже просто умелые маркетологи). А раз есть база и отказываться от не планирую, почему бы и не хранить локализованные сообщения в ней? 
Единственно, что мотивировать это лучше аргументированно и без эмоций, конечно. =)
Еще раз благодарю за подсказки, даже немного стыдно, что boost::localization просмотрел, сейчас исправлю.

Автор: bsa 23.12.2011, 11:24
Цитата(drug007 @  23.12.2011,  08:08 Найти цитируемый пост)
Еще раз благодарю за подсказки, даже немного стыдно, что boost::localization просмотрел, сейчас исправлю. 

ничего постыдного. эта либа появилась совсем недавно - в текущей версии boost.

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