基本的なプログラム

なんとなく、glibmmを使えるようになっておこうと思った。
http://www.gtkmm.org/
glibmmはglibのC++版である。
とりあえず、入力した文字列をそのまま出力するプログラムを書いてみた。

#include 
#include 
#include 

using namespace std;
using namespace Glib;

class Application {
public:
    Application() 
    {
        std::string charset;

        /* イベントループの作成 */
        _main_loop = Glib::MainLoop::create();

        /* 入力は標準入力から取得する */
        /* Glibmm の入出力は、Glib::IOChannel を使う。*/
        _in = IOChannel::create_from_fd(0);

        /* 文字列を読み込む際に、UTF-8に変換するため、入力の文字コードを
         * IOChannelに設定する。
         * main() で setlocale("") しているため、環境変数で指定された
         * 文字コードが Glib::get_charset() で取得可能である
         */
        get_charset(charset);
        _in->set_encoding(charset);

        /* 入力と入力があった際の動作を関連付ける。*/ 
        Glib::signal_io().connect(
            sigc::mem_fun(*this, &Application::io_handler),
            _in, Glib::IO_IN | Glib::IO_HUP);

        _main_loop->run();
    }

    /* 入力があった際の動作 */
    bool
    io_handler(Glib::IOCondition condition)
    {
        ustring line;
        IOStatus result;

        try {
            /* 一行読込 */
            result = _in->read_line(line);
            switch (result) {
            case Glib::IO_STATUS_EOF:
            case Glib::IO_STATUS_ERROR:
                /* EOF の場合は、イベントループから抜ける */
                _main_loop->quit();
                break;
            case Glib::IO_STATUS_AGAIN:
                /* 何もしない */
                break;
            case Glib::IO_STATUS_NORMAL:
                /* 読み込めた場合は、そのまま出力する */
                cout <<  line << flush;
                break;
            default:
                abort();
            }
        } catch (Error& e) {
            /* Glib::IOChannel::read_line() での例外を捕捉する */
            /* glibmm での例外は Glib::Error から派生している */
            try {
                cout << e.what() << endl;
            } catch (Error& e) {
                /* e.what() は UTF-8 なので文字コードの変換が行われるため、
                 * その失敗に時の例外を捕捉する。*/
                ;
            }
            _main_loop->quit();
        }

        return true;
    }

private:
    RefPtr  _main_loop;
    RefPtr _in;
};

int
main(int argc, char *argv[])
{
    /*
     * locale の設定
     * C++ なので、std::locale::global(std::locale("")) を使うべきだが、
     * 私の環境では C 以外の locale がサポートされていなかった。
     * そのため、C スタイルで設定した。
     * 環境変数LANG に ja_JP.eucJP などを指定すると日本語を受け付けるよ
     * うになる。
     */
    setlocale(LC_ALL, "");

    /* 主処理は Application のコンストラクタで実行 */
    Application app;

    return 0;
}

Makefile はこんな感じで作った。pkg-config でライブラリとヘッダのパスを取得している。

SRCS=main.cpp
FILES=${SRCS:.cpp=.o}
TARGET=test
CFLAGS= -g -Wall `pkg-config --cflags glibmm-2.4`
LDFLAGS=`pkg-config --libs glibmm-2.4`

all: ${TARGET}

${TARGET}: ${FILES}
	g++ ${LDFLAGS} ${CFLAGS} -o ${TARGET} ${FILES}

clean:
	rm -rf ${TARGET} ${FILES}