Gettext działa tylko zgodnie z językiem ustawionym w systemie

0

Cześć!

Środowisko VS 2008. Nie mogę dojść do ładu z gettextem. Na potrzeby znalezienia problemu zrobiłem nową "Windows Form Application". W konstruktorze formularza dodałem:

		Form1(void)
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			//
			#undef GetCurrentDirectory	// winbase.h
				char* loc = setlocale(LC_ALL, "");
				if (loc != NULL)
				{
					char *locale_dir = (char*)(void*)Marshal::StringToHGlobalAnsi(Directory::GetCurrentDirectory() + "\\debug\\locale");

					if (bindtextdomain(PACKAGE_NAME, locale_dir) != NULL)
					{
						if (textdomain(PACKAGE_NAME) != NULL)
						{
							//if (setlocale( LC_ALL, "Polish_Poland" ) == NULL) 
							//if (setlocale( LC_ALL, "English_United States" ) == NULL) 
							if (setlocale( LC_ALL, "German_Germany" ) == NULL) 
								MessageBox::Show("No translation file", "Error!", MessageBoxButtons::OK, MessageBoxIcon::Error);
						}
					}
				}
				setlocale(LC_NUMERIC, "C");
				this->Text = _d("(Title)");
		}

Generalnie standardowy init ustawień lokalnych. Wszystkie języki są odczytywane, setlocale nigdy nie zwraca NULL. Problem jest w tym, że funkcja gettext nie chce "słuchać" mojego ustawienia setlocale. Jedyną metodą żeby zmienić ustawienia lokalizacji dla gettext-a jest zmiania języka w ustawieniach systemu. Jak tam zmieniam na DE czy EN to gra, ale jak zmieniam za pomocą setlocale to i tak zawsze przetłumaczy zgodnie z ustawieniami w systemie.

Zrobiłem do tego dodatkowy test. Analogicznie jak tutaj:
http://msdn.microsoft.com/en-us/library/vstudio/x99tb11d.aspx

// Retieve the time
_time64(&ltime);
_gmtime64_s(&thetime, &ltime);

Po zmianie locale na inne niż ma system użyłem funkcji standardowych do odczytu daty. I tutaj locale działają tak jak ustawię. Gettext tłumaczy mi tak jak mam system czyli teraz polski, a datę funkcje standardowe mogą wyświetlić np z niemieckimi locale.

Na początku mam jeszcze takie makra:

#define _(text) gettext(text)
#define _d(text) gcnew System::String(gettext(text))
#define PACKAGE_NAME "lang"	// nazwa plikow *.mo

Wiecie może dlaczego funkcja gettext nie chce słuchać moich ustawień locale?

1

char locale_dir = (char)(void*)Marshal::StringToHGlobalAnsi(Directory::GetCurrentDirectory() + "\debug\locale");

Tu masz wyciek, bo pamięć trzeba zwolnić przez FreeHGlobal.
Mikroskopijny wyciek co prawda, ale w oczy kole ;-)

#include <msclr/marshal.h>
...
{
    msclr::interop::marshal_context ctx;
    const char* locale_dir = ctx.marshal_as<const char*>(Directory::GetCurrentDirectory() + "\\debug\\locale");
}

Pamięć zostanie zwolniona gdy ctx wyjdzie z zasięgu.

Wiecie może dlaczego funkcja gettext nie chce słuchać moich ustawień locale?
Wydaje mi się, że nie ma w zwyczaju, a setlocale jest potrzebne do prawidłowego ustawienia kodowania, a nie powoduje wyboru języka...

0

Dzięki za info o tym wycieku. Siedzę w embedded a całe CLI to dla mnie zło konieczne :)

Azarien napisał(a):

Wydaje mi się, że nie ma w zwyczaju, a setlocale jest potrzebne do prawidłowego ustawienia kodowania, a nie powoduje wyboru języka...

No dobra, ale to w jaki sposób z poziomu aplikacji jest robiona zmiana języka. Libintl rozszerza locale o kategorię LC_MESSAGES a sama biblioteka gettext na podstawie wybranego kodowania powinna wybierać wiadomości z odpowiadającego pliku lokalizacji. Kilka lat temu robiłem tak w borlandzie i to chodziło a język wybrany w systemie nie miał nic do rzeczy.

Dodatkowo jedną rzecz sprawdziłem http://www.gnu.org/software/gettext/FAQ.html#windows_woe32

  • Check that you are using the -MD option in all compilation and link command lines. Otherwise you might end up calling the putenv() function from Microsoft's libc.lib, whereas intl.dll is using the getenv() function from Mictosoft's msvcrt.lib.
  • Check that you set the environment variable using both SetEnvironmentVariable() and putenv(). A convenient way to do so, and to deal with the fact that some Unix systems have setenv() and some don't, is the following function.

I ustawiam zmienne środowiskowe np. LANG=de_DE za pomocą SetEnvironmentVariableA() i jednocześnie putenv() ale nadal efekt jest ten sam. Szkoda, że już nie mam kompa z XP. Może na Win7 się coś pozmieniało w tym temacie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1