如何将char*转为wchar_t*并在Python中正确显示宽字符串?
解决方案:还原UTF-16LE格式的宽字符串
你的核心问题是:EP_ProtectedStringByID返回的是UTF-16LE编码的字节序列(ASCII字符后跟0字节是小端UTF-16的典型特征),而mbstowcs是用来将多字节字符串(如UTF-8)转换为宽字符的工具,完全不适用这种场景,才会出现遇\0截断的问题。下面提供两种可行方案:
方法一:Python层直接解码(简单高效)
既然buf_string_2本身是bytes类型,直接用Python原生的编码解码功能处理即可,无需C层转换:
# 截取有效长度的字节后,用utf-16-le解码 target_str = buf_string_2[:buf_size].decode('utf-16-le') print(target_str)
方法二:Cython层正确处理宽字符
如果必须在Cython逻辑内完成转换,直接将char*强制转为wchar_t*(Windows平台下wchar_t默认就是UTF-16LE),再调用Python的宽字符转字符串接口:
cdef extern from "Python.h": object PyUnicode_FromWideChar(const wchar_t* w, Py_ssize_t size) if EP_ProtectedStringByID(2, buf_string_2, buf_size) != 0: # 直接强制转换字节序列为宽字符指针 cdef wchar_t* wide_buf = <wchar_t*>buf_string_2 # 计算宽字符数量:总字节数除以单个宽字符的字节数 cdef Py_ssize_t wide_len = buf_size // sizeof(wchar_t) pystr_2 = PyUnicode_FromWideChar(wide_buf, wide_len) wide_string = str(pystr_2) print('WideString :', wide_string)
关键说明
- 原始输出的字节序列中,ASCII字符以
字符码+0的形式存储,这是UTF-16LE(小端字节序UTF-16)的标准格式。 mbstowcs的设计逻辑是处理以\0结尾的多字节字符串,所以遇到第一个\0就会停止转换,完全不适合处理宽字节序列。- 解码时务必截取
buf_size长度的字节,避免包含内存中多余的无效内容。
内容的提问来源于stack exchange,提问作者MelectronVolt
相关产品推荐
相关产品推荐

