2016年6月8日水曜日

[OCaml]cursesで文字化け

OCamlでcursesを使ってピコピコゲームでも作ろうかと思い、以前にcursesを使ったコードを動かしてみたら、 日本語が文字化けするようになっていた。
Cライブラリのsetlocale(LC_ALL,"")を実行した後に、cursesを使えば文字化けしないことが分かった。
setlocale関数の呼び出しは ctypesを使うと簡単に呼び出すことができる。
opamでパケージが用意されているので、以下のコマンドでインストールできる。
$ opam install ctypes ctypes-foreign

コードはこちら。
open Core.Std
open Ctypes
open PosixTypes
open Foreign

let time = foreign "time" (ptr time_t @-> returning time_t)

(* char *setlocale(int category, const char *locale); *)
let setlocale = foreign "setlocale" (int @-> string @-> returning string)

let () =
  let locale_str = setlocale 6(*LC_ALL*) "" in
  let module C = Curses in
  let main_window = C.initscr () in
  let err = C.mvwaddstr main_window 10 2 "hello, world!" in
  let err = C.mvwaddstr main_window 11 2 "こんにちは、世界!" in
  let err = C.refresh () in
  Unix.sleep 5;
  C.endwin ();
  printf "locale_str=%s\n" locale_str

ビルドはお手軽なcorebuildを使った。
$ corebuild -pkg curses -pkg ctypes.foreign sample.native
Debian Jessie 64bit では、LC_ALL = 6 だったので、直接コード中に書いたが、このようなヘッダで定義されている定数はどのように定義するのが正しいのだろうか。

参考