LINUX.ORG.RU

Использование gettext в .so/.a

 ,


0

1

Вот такой вопрос возник, а каким образом правильно воспользоваться gettext'ом в библиотеке? Если с обычным приложением всё понятно:

...
int main(void) {
    setlocale( LC_ALL, "" );
    bindtextdomain( "hello", "/usr/share/locale" );
    textdomain( "hello" );
    printf( gettext( "Hello, world!\n" ) );
    exit(0);
}

То как использовать во внешней библиотеке? Надеятся что приложение сделает setlocale и bindtextdomain и вызывать dgettext?

★★★★★

Надеятся что приложение сделает setlocale и bindtextdomain

А кто сказал, что оно сделает bindtextdomain куда нужно библиотеке?

Я в своем велосипеде так делал:

static char *olddomain = NULL, *olddir = NULL, *lang = NULL;
void setloc(){
        if(lang) return;
        lang = getenv("HTTP_ACCEPT_LANGUAGE");
        if(!lang) return;
        if(lang && (strncmp(lang, "ru", 2) == 0)){
                DBG("RU");
                setlocale(LC_ALL, "ru_RU.koi8-r");
                setlocale(LC_NUMERIC, "C");
        }else
                setlocale(LC_ALL, "C");
}

void set_locale(char *text_domain, char *localedir){
        setloc();
        if(!text_domain) text_domain = GETTEXT_PACKAGE;
        if(!localedir) localedir = LOCALEDIR;
        if( (olddomain = strdup(textdomain(NULL))) )
                olddir = strdup(bindtextdomain(olddomain, NULL));
        textdomain(text_domain);
        bindtextdomain(text_domain, localedir);
}

void restore_locale(){
        if(!olddomain) return;
        textdomain(olddomain);
        if(olddir) bindtextdomain(olddomain, olddir);
        FREE(olddomain);
        FREE(olddir);
}

char *explain_error(int errcode){
        char *msg;
        set_locale(NULL, NULL);
        errcode = abs(errcode);
        msg = _(ErrMessages[errcode]);
        restore_locale();
        return msg;
}

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

Вот мысля тут появилась.


По идее надо только один раз сделать bindtextdomain(<lib domain>, <lib locale dir>);
И сделать это на этапе инициализации.
А в дальнейшем использовать dgettext, что бы не переключать каждый раз туда-сюда.
Вот только не помню, а в сях есть возможность скрытой инициализации библиотеки?
В плюсах-то можно проделать такое извращение.

WatchCat ★★★★★ ()
Ответ на: Вот мысля тут появилась. от WatchCat

dgettext

Не знал про эту функцию.

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

в сях есть возможность скрытой инициализации библиотеки?

По-моему нет

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

Не знал про эту функцию.

Э-э-э так man 3 gettext выдаёт описание сразу трёх: gettext, dgettext и dcgettext.

Вот интересно только, если домены библиотеки и приложения будут

различаться, что получится.
Да по идее ничего особенного.
Я так понимаю что libintl содержит ассоциативный массив домен - путь, а textdomain указывает только домен по умолчанию, который используется при вызове gettext() и dgettext(NULL,).

По-моему нет

А если сделать так:
lib.h
-----------------
#ifndef _LIB_H_
#define _LIB_H_
static int dummy = initialize();
#endif
-----------------
lib.c
-----------------
int initialize(){
//init code here
}
-----------------

PS Почему-то нет выбора разметки LORCODE :\

WatchCat ★★★★★ ()
Ответ на: Вот мысля тут появилась. от WatchCat

в сях есть возможность скрытой инициализации библиотеки?

В голых сях нет. В частных случаях - можно. Например, __attribute__((constructor)) в GCC/ELF.

const86 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.