Visual Cpp Gettext - Luke31/i18n-cs GitHub Wiki

Example Project: CppGettext

Introduction

Instead of using resoures, we may use the GNU gettext library for Visual C++ internationalization. Here are all the required elements for GNU gettext on Windows described: GNU gettext on Windows - How do I compile, link and run a program that uses the gettext() function?

Hint: The GNU gettext runtime is LGPL (Source: GNU Appendix C Licenses). Any modification to the gettext runtime (not your code) must be open sourced.

Required libraries and tools

Following steps must be taken to use GNU gettext with Visual C++:

  1. To run an application with GNU gettext you need following libraries: intl.dll (iconv.dll? Not in runtime!)

    Available in gettext-runtime (For example project the version gettext-runtime_0.18.1.1-2_win32.zip from the Gnome FTP is used)

  2. To develop an application with GNU gettext you need following files: libintl.h and intl.lib

    Available in gettext-runtime-dev (For example project the version gettext-runtime-dev_0.18.1.1-2_win32.zip from the Gnome FTP is used)

  3. To comfortably generate your UTF8 .po files from your C++ source code files you may use Poedit. This will also generate the required .mo files when saving a translation. Poedit is open source under the MIT license

    • Alternatively, you may stick to the classic command-line approach. For this you need: xgettext.exe and msgfmt.exe

      Available in gettext-tools-dev (For example project the version gettext-tools-dev_0.18.1.1-2_win32.zip from the Gnome FTP is used)

      OR: install Poedit and you'll find those tools under: Poedit/GettextTools/bin

Project in Visual Studio, Visual Cpp

There's an archive with many gettext examples (besides this one of course) from GNU gettext available here: gettext-examples-dev_0.18.1.1-2_win32.zip from the Gnome FTP. Mainly the hello-c++ project is of most interest.

Following steps must be taken to create a Visual C++ project using GNU gettext:

  1. Add files:

    • libint.h to $(ProjectDir)/include/libint.h
    • intl.lib to $(ProjectDir)/lib/intl.lib
    • intl.dll to $(ProjectDir)/External/intl.dll
  2. Project settings -> Configuration Properties (Debug AND/OR Release):

    • C/C++ -> General -> Output Directory -> Set to $(ProjectDir)$(Configuration) (Not needed, but convenient for this tutorial)

    • C/C++ -> General -> Additional Include Directories -> Add include-folder (-I Compiler Parameter)

    • C/C++ -> Code Generation -> Runtime Library -> Set to /MD or /MDd for debug (However /MT and /MTd also seem to work and are used in example-project for easier distribution of .exe)

    • Linker -> General -> Additional Library Directories -> Add lib-folder

    • Linker -> Input -> Additional Dependencies -> Add intl.lib-files (-L Linker Parameter)

    • Build-Events -> Post-Build Event -> Set Command Line

        xcopy /y /e /d "$(ProjectDir)External" "$(OutDir)"
      
  3. To your .cpp-file you wish to translate set:

    (See CppGettext.cpp)

     #include <iostream>
     #include <io.h> //for setting outputmode UNICODE
     #include <fcntl.h> //contains _O_U16TEXT
    
     // Get gettext(), textdomain(), bindtextdomain() declaration.
     #include "libintl.h"
     // Define shortcut for gettext().
     #define _(string) gettext (string)
     #include <locale>
     #include <codecvt>
     #include <string>
     
     //Convert string in current system MultiByte code-page to widechar
     const std::wstring stow(const std::string& str)
     {
     	if (str.empty()) return L"";
     	int size_needed = MultiByteToWideChar(CP_ACP, 0, &str[0], (int)str.size(), NULL, 0); //CP_UTF8
     	std::wstring wstrTo(size_needed, 0);
     	MultiByteToWideChar(CP_ACP, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed); //CP_UTF8, CP_ACP
     	return wstrTo;
     }
     
     int wmain(int argc, wchar_t* argv[])
     {
     	//Set output Unicode without BOM
     	_setmode(_fileno(stdout), _O_U16TEXT); //_O_WTEXT (with BOM)
     	//stdout may now be written to file (First character must be ASCII if output is written to file)
     	std::wcout << L"Enabling Unicode support" << std::endl;
    
     	//Set locale
     	setlocale(LC_ALL, ""); //Set locale to environment
     	
     	...
     	
     	//Gettext
     	textdomain("cppgettext");
     	bindtextdomain("cppgettext", "locale");
    
     	std::wcout << stow(_("Hello world")) << std::endl;
     }
    
  4. Open Poedit and save a new .po file under: $(ProjectDir)/External/locale/ja/LC_MESSAGES/cppgettext.po

  5. In Poedit with cppgettext.po opened:

    • Catalogue -> Properties -> Sources keywords -> Add new keyword underscore _
    • Catalogue -> Properties -> Sources paths -> Paths -> Add files... -> CppGettext.cpp (Your cpp-file)
    • Catalogue -> Update from sources
    • Translate your strings
    • Save
  6. Debug your application for test

⚠️ **GitHub.com Fallback** ⚠️