local ffi = require "ffi" local kernel32 = ffi.load("kernel32") ffi.cdef[[ int Beep(int x, int y); typedef unsigned int UINT; typedef unsigned int DWORD; typedef const char * LPCSTR; typedef char * LPSTR; typedef wchar_t * LPWSTR; typedef const wchar_t *LPCWSTR; typedef int *LPBOOL; int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar ); int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar); ]] local CP_UTF8 = 65001 local function to_utf16(s) local needed = kernel32.MultiByteToWideChar(CP_UTF8, 0, s, -1, NULL, 0) local buf = ffi.new("wchar_t[?]", needed) local written = kernel32.MultiByteToWideChar(CP_UTF8, 0, s, -1, buf, needed) return ffi.string(buf, written*2) end local function to_utf8(s) local needed = kernel32.WideCharToMultiByte(CP_UTF8, 0, s, -1, nil, 0, nil, nil) local buf = ffi.new("char[?]", needed) local written = kernel32.WideCharToMultiByte(CP_UTF8, 0, s, -1, buf, needed, nil, nil) return ffi.string(buf, written - 1) end return {to_utf8=to_utf8, to_utf16=to_utf16}