Ruby から Win32API を叩いて文字コード変換
意外と需要があるんじゃないかと思って書いてみた。Ruby 1.9 用です。Codepage は Code Page Identifiers あたりを見ればいいのですが、この API では全て叩けるわけじゃないので、改めて MLang 版を書くかも。
require 'dl/import' module MSEncode extend DL::Importer dlload "kernel32" typealias("UINT", "unsigned int") typealias("DWORD", "unsigned long") typealias("LPCSTR", "char *") typealias("LPWSTR", "wchar_t *") typealias("LPCWSTR", "wchar_t *") typealias("LPSTR", "char *") typealias("LPBOOL", "int") # int MultiByteToWideChar( # UINT CodePage, # DWORD dwFlags, # LPCSTR lpMultiByteStr, # int cbMultiByte, # LPWSTR lpWideCharStr, # int cchWideChar # ); extern "int MultiByteToWideChar(UINT,DWORD,LPCSTR,int,LPWSTR,int)" # int WideCharToMultiByte( # UINT CodePage, # DWORD dwFlags, # LPCWSTR lpWideCharStr, # int cchWideChar, # LPSTR lpMultiByteStr, # int cbMultiByte, # LPCSTR lpDefaultChar, # LPBOOL lpUsedDefaultChar # ); extern "int WideCharToMultiByte(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL)" def MSEncode.mbtwc(code, str) rvalue = MSEncode.MultiByteToWideChar(code, 0, str, str.length, "", 0) raise if rvalue == 0 res = "\x00" * rvalue rvalue = MSEncode.MultiByteToWideChar(code, 0, str, str.length, res, res.length) raise if rvalue == 0 return res end def MSEncode.wctmb(code, str) rvalue = MSEncode.WideCharToMultiByte(code, 0, str, str.length, "", 0, 0, 0) if rvalue == 0 DL::CFunc.win32_last_error raise end res = "\x00" * rvalue rvalue = MSEncode.WideCharToMultiByte(code, 0, str, str.length, res, res.length, 0, 0) raise if rvalue == 0 return res end def MSEncode.iconv(from, to, str) wc = MSEncode.mbtwc(from, str) mb = MSEncode.wctmb(to, wc) return mb end end puts MSEncode.iconv(932, 65001, "ほえほえふがふが")