.NET Profiling API在Linux环境下获取程序集名称出现乱码的问题
NET Profiling API在Linux环境下获取程序集名称出现乱码的问题
兄弟,我之前做跨平台.NET Profiler的时候也踩过一模一样的乱码坑,咱们来捋清楚问题根源和解决办法:
问题出在哪?
Windows和Linux下的wchar_t长度不一样:Windows里wchar_t是2字节(刚好对应UTF-16编码),但Linux里wchar_t是4字节(对应UTF-32)。而.NET Profiling API不管在哪个平台,返回的程序集名称都是UTF-16编码的。你直接用wchar_t数组接收,在Linux下就会把每个2字节的UTF-16字符拆成两个4字节的wchar_t,内存数据直接错位,自然就显示乱码了。至于你设置的std::setlocale(LC_ALL, ""),完全没用——因为API返回的编码和系统locale根本不挂钩。
怎么解决?
核心思路就是:用固定2字节的类型接收UTF-16数据,再转成Linux默认的UTF-8编码字符串。
这里给你修改后的代码示例:
#include <codecvt> #include <string> #include <cstdint> bool CAssemblyManager::Initialize(AssemblyID assemblyId) { ULONG nameLength = 0; HRESULT hr = S_OK; // 第一步:获取UTF-16格式的名称长度 hr = _corProfilerInfo2->GetAssemblyInfo(assemblyId, 0, &nameLength, nullptr, nullptr, nullptr); if (FAILED(hr)) { // 记得处理错误,比如打日志或者返回失败 return false; } // 用uint16_t数组接收UTF-16数据(uint16_t在所有平台都是2字节) uint16_t* nameBuffer = new uint16_t[nameLength]; if (!nameBuffer) { return false; } // 第二步:获取实际的程序集名称(UTF-16格式) hr = _corProfilerInfo2->GetAssemblyInfo(assemblyId, nameLength, &nameLength, nameBuffer, nullptr, nullptr); if (FAILED(hr)) { delete[] nameBuffer; return false; } // 第三步:把UTF-16转成Linux支持的UTF-8字符串 std::wstring_convert<std::codecvt_utf8_utf16<uint16_t>, uint16_t> converter; // 注意要去掉末尾的null字符,避免转换后多一个空字符 std::string assemblyName = converter.to_bytes(nameBuffer, nameBuffer + nameLength - 1); // 这里就可以正常使用assemblyName了,比如打印或者存储 // printf("Assembly Name: %s\n", assemblyName.c_str()); // 别忘了释放内存 delete[] nameBuffer; return true; }
额外注意事项
- 如果你用的是C++17及以上版本,
std::wstring_convert会被标记为deprecated,这时候可以用第三方库(比如ICU)或者自己实现一个简单的UTF-16到UTF-8的转换函数。 - 一定要检查每次调用
GetAssemblyInfo的HRESULT返回值,避免内存泄漏或者无效数据。 - 不要依赖系统locale来处理这个问题,Profiler API的字符串编码是固定的UTF-16,和系统设置无关。
备注:内容来源于stack exchange,提问作者RANJITH M
相关产品推荐
相关产品推荐

