请问你这个 wchar 是哪个 wchar? 可否提供更详细的信息?
- 如果你指的是 Win32 API 的
WCHAR
, 它是 UTF-16 内码,little endian (UTF-16LE).
- 如果你指的是
wchar_t
, 不同平台的 wchar_t
是不同长度的,有的是是 UTF-16 有的是 UTF-32, 还有别的,而且有 big endian/little endian 的区别 (x86 一般都是 little endian, 不过最好自己做下试验先).
弄清楚内码以后,强转成 char* 交给 rb_enc_str_new
, 然后再调用 rb_str_encode
或者在 ruby 方面用 String#encode
方法转换回 utf-8 的字符串。
以 Win32 API WCHAR 为例,它是 UTF-16LE 内码,所以对应的字节数目是字符串长度乘以 2, 假设你有 wchar_ptr
, wchar_len
#include <ruby/encoding.h>
.....
volatile VALUE s;
s = rb_enc_str_new((char*)wchar_ptr, wchar_len * 2, rb_enc_find("UTF-16LE"));
s = rb_str_encode(s, rb_enc_from_encoding(rb_utf8_encoding()), 0, Qnil);
假设你有个 Ruby 字符串 s
s = rb_str_encode(s, rb_enc_from_encoding(rb_enc_find("UTF-16LE")), 0, Qnil);
WCHAR* wchar_ptr = (WCHAR*)RSTRING_PTR(s);
int wchar_len = RSTRING_LEN(s) / 2;
基础知识见:
http://www.rubydoc.info/stdlib/core/file/README.EXT
找 API 只能看头文件咯:
http://rxr.whitequark.org/mri/ident?i=rb_str_encode
另外,如果你在 C++, 那个强制转换会稍微麻烦点,得用 reinterpret_cast<>