CP_THREAD_ACP与CP_ACP
在使用MultiByteToWideChar的时候,大部分都知道上述两个参数,MSDN上的解释也是简单到极致。通常我们会选择使用CP_ACP,但是总有人会在没有真正明白它们之间的区别前使用CP_THREAD_ACP。
上周收到一个日方的Bug报告。Bug的上下文基本是这样的:有一个功能是记录设备信息一览的,并可以将这些信息输出到一个文件(格式有很多)。这个文件可以手动实时获取,也可以设置日期和时间定时获取。
Bug的现象是:在英语和日语的环境下,一切都OK。但是在俄语下定时获取文件的功能失效,手动获取确实OK的。
我们模拟俄语的环境是在非俄语的OS下,改变控制面板中的“地域”中的信息为俄语,包括User Locale和System Locale还有位置。
int usize = ::MultiByteToWideChar(CP_THREAD_ACP, 0, name, (int)strlen(name) + 1, NULL, 0); wchar_t *unicode = new wchar_t[usize];
if(NULL != unicode)
{
ZeroMemory(unicode, usize * sizeof(wchar_t)); // Convert
::MultiByteToWideChar(CP_THREAD_ACP, 0, name, (int)strlen(name), unicode, usize); // Make Key-source
unsigned char key_message[DM_MAX_SIZE_OF_PARAMS]; memcpy( key_message, SNMPV3_HASH_KEY, strlen(SNMPV3_HASH_KEY) );
memcpy( key_message + strlen(SNMPV3_HASH_KEY),
unicode, usize * sizeof(wchar_t) );
memcpy( key_message + strlen(SNMPV3_HASH_KEY) + usize * sizeof(wchar_t),
hash, SIZE_OF_MESSAGE_DIGEST ); // Make hash
md5.MakeMD5(key_message,
strlen(SNMPV3_HASH_KEY) + usize * sizeof(wchar_t) + SIZE_OF_MESSAGE_DIGEST,
key_data);
if( NULL != key ) memcpy( key, key_data, SIZE_OF_MESSAGE_DIGEST ); delete[] unicode;
}
上面的代码片段是我摘自过程中的出现问题的一段。
后来经过分析,执行写文件的功能是在一个单独的F.exe中做的,而F.exe调用了S.dll中的函数,上述代码就是处于S.dll中。定时写文件的功能是因为主程序有个服务,当时间到达后由服务创建F.exe来执行功能。
在主程序中,手动执行保存文件动作是,进入S.dll中的Thread Locale是和System Locale相同的,为0x0419,即俄语。所以执行MultiByteToWideChar没问题,也就能产生正确的Key用于解密。但是在定时的情况下,由服务创建F.exe进程进入S.dll时,Thread Locale是0x0411,即日语(OS为日语),System Locale还是0x0419。这种情况下,使用MultiByteToWideChar转换的字符串会是乱码,最终也就导致了程序的异常。
在此有个不明白的地方是,为什么由服务启动F.exe进程,执行进程的主线程的Thread Local会是0x0411。正常情况下启动F.exe(通过主程序Create或手动启动),Thread Locale和System Locale都是相同的。CreateProcess中也没有办法来设置Thread Locale让主线程运行在指定的Locale下。
这个也说明了另外一个问题,通过过更改地域信息区模拟其他语言环境还是会存在一些缺陷。上面代码如果是运行在俄语的OS下我想是不会出现这样的问题。
Conclusion
在我们不确定线程的code page时,使用CP_THREAD_ACP并不是一个好主意。因为我们没有办法确定Thread Locale和System Locale是一致的,也就是System Locale和User Locale之间可能会存在不一致性。这篇文章可以做个参考。
CP_THREAD_ACP与CP_ACP的更多相关文章
- Windows上的字符转换之CP_ACP和CP_OEMCP
原文地址:http://blog.sina.com.cn/s/blog_53c1950a010158mw.html Windows API函数MultiByteToWideChar用于多字节编码字符串 ...
- CP_ACP : CP_OEMCP
// filesystem windows_file_codecvt.cpp -----------------------------------------// // Copyright Bema ...
- 关于多字节、宽字节、WideCharToMultiByte和MultiByteToWideChar函数的详解
所谓的短字符,就是用8bit来表示的字符,典型的应用是ASCII码. 而宽字符,顾名思义,就是用16bit表示的字符,典型的有UNICODE. **************************** ...
- MULTIBYTETOWIDECHAR的与WIDECHARTOMULTIBYTE的参数详解及相互转换
第一个就是宽字符到多字节字符转换函数,函数原型如下: int WideCharToMultiByte( UINT CodePage, DWORD dwFlags, LPCWSTR lpWideChar ...
- 函数 MultiByteToWideChar() 详解
函数原型: int MultiByteToWideChar( UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cchMultiByte ...
- 函数WideCharToMultiByte() 详解
函数原型: int WideCharToMultiByte( UINT CodePage, DWORD dwFlags, LPWSTR lpWideCharStr, int cchWideChar, ...
- MultiByteToWideChar和WideCharToMultiByte用法详解
今天写ini文件的时候发现的问题: TCHAR temp[]; //strcpy_s(temp, request.newVersion); MultiByteToWideChar(CP_ACP, , ...
- php连接Access数据库的三种方法
http://www.php100.com/html/webkaifa/PHP/PHPyingyong/2009/1115/3524.html 虽然不是一个类但先放这儿吧 最近想把一个asp的网站改成 ...
- 使用Win32 API 查找文件
头文件:#include <windows.h> //FindFirstFile() 获得指定目录的第一个文件 HANDLE FindFirstFile( LPCTSTR lpFileNa ...
随机推荐
- sublime text 使用
一.在sublime text中创建html.css.js文件 ctrl+shift+p(调出控制台) 然后输入 Set Syntax:html(也可以输入:ssh) Set Syntax:css ...
- java多线程之停止线程
/*1.让各个对象或类相互灵活交流2.两个线程都冻结了,就不能唤醒了,因为根据代码要一个线程活着才能执行唤醒操作,就像玩木游戏3.中断状态就是冻结状态4.当主线程退出的时候,里面的两个线程都处于冻结状 ...
- javaee学习-新建servlet 直接返回html
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExcepti ...
- Fire Net
Fire Net Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Subm ...
- 24种设计模式--访问者模式【Visitor Pattern】
今天天气不错,绝对是晴空万里,骄阳似火呀,好,我们今天来讲访问者模式,我们在前面讲了组合模式和迭代器模式,通过组合模式我们能够把一个公司的人员组织机构树搭建起来,给管理带来非常大的便利,通过迭代器模式 ...
- Linux---vi编辑器必会操作
移动光标: (1)基本的上下左右:通过箭头按键控制 (2)跳到一行的末尾:键盘"end" (3)跳到一行的开头:键盘"home" (4)跳到最后一行:shift ...
- 关闭一个winform窗体刷新另外一个
例如Form1是你的主窗体,然后Form2是你的要关闭那个窗体,在Form1中SHOW FORM2的窗体那里加上一句f2.FormClosed += new FormClosedEventHandle ...
- web页面显示折叠树菜单笔记
zTree -- jQuery 树插件 http://pan.baidu.com/s/1skwh94h
- Delphi IDE下载全地址
Delphi IDE下载全地址: http://pan.baidu.com/share/home?uk=1060104307#category/type=0 还是网友伟大呀.当然有钱的公司还是应该多多 ...
- map遍历的三种基础用法
java中遍历MAP的几种方法 Java代码 Map<String,String> map=new HashMap<String,String>(); map.put(& ...