VS2010中char与宽字符的问题

本文介绍了解决Visual Studio 2010中由于默认启用Unicode导致的编译错误方法。通过调整项目配置,从Unicode转为未设置状态,并提供了字符串转换的正确实践。

使用VS2010 提示错误 : error C2664: 'LoadImageW' : cannot convert parameter 2 from 'char [20]' to 'LPCWSTR'“char [20]”转换为“LPCWSTR”


     问题的原因:VS2010默认采用宽字符UNICODE编码方式,定义了Unicode,因此相关的字符串必须为unicode字符串,而非ascii字符串。

LPCWSTR中的W是宽字符的意思,是UNICODE,就是说不是传统的char这种单字节字符,而是一个字符占两字节.
编译器把LoadImage解释成了LoadImageW,说明代码中某个地方定义了UNICODE开关,编译环境成了宽字节的,要把这个定义去掉.

Win32 API也分2中版本, MessageBoxA / MessageBoxW,,,MessageBox根据是否定义_UNICODE宏而定义到其中一个版本。

  
     正确的解决方案是
选择【项目菜单】->【最后的属性】->【配置属性】->【常规】->【项目默认值】->unicode改为未设置。


     几个注意事项:

1,若定义UNICODE,相关字串必须使用Unicode的字串而非ANSI字串也就是wchar_t * wfilename;

2,指定的Unicode字串常数请加L“...”;例如wchar_t *
wfilename= L“HelloWorld”;

3,ansi字串就是传统的char*)wchar_t的*unicode的的字符串互转请用MultiByteToWideCharWideCharToMultiByte这两个API函数。

4,如果不太unicode的,那么不要UNICODE定义,用传统的方式处理。
 
    如何转换呢 ?

错误方法一:
wsprintf(buffer,L"WM_CHAR: Character = %c ",ascii_code);
TextOut(hdc, 0,0,(LPCWSTR)buffer, strlen(buffer));
这个只能显示第一个字母“W”
错误方法二:
sprintf((LPCWSTR)buffer,L"Key State = 0X%X ",key_state);
TextOut(hdc, 0,16,(LPCWSTR)buffer, strlen(buffer));
这个出现的是乱码!
错误方法三:
sprintf(buffer,L"Key State = 0X%X ",key_state);
TextOut(hdc, 0,16,buffer, strlen(buffer));
这个提示不能将char[80]转换成LPCWSTR
强制类型转换是不行的,因为一个是字符占一个字节,一个占两个字节,但是sprintf等函数是不知道的。

方法一:使用WideCharToMultiByte和 MultiByteToWideChar函数
 

代码如下:
#include
#include
#define STRSAFE_NO_DEPRECATE
#include // for String... functions
#include // for _ASSERTE


CStringW ConvertW(CString str, int sourceCodepage)
{
//int len=str.GetLength();


int unicodeLen=MultiByteToWideChar(sourceCodepage,0,str,-1,NULL,0) + 1;


wchar_t* pUnicode;
pUnicode=new wchar_t[unicodeLen];


memset(pUnicode,0,(unicodeLen)*sizeof(wchar_t));


MultiByteToWideChar(sourceCodepage, CP_ACP, str, -1, (LPWSTR)pUnicode, unicodeLen);


CStringW rt = pUnicode;


//delete pUnicode;
SAFE_DELETEGROUP( pUnicode );

return rt;


}


调用:
CStringW wszTemp = ConvertW( Filename, CP_ACP);
LPWSTR pwStr = wszTemp.GetBuffer();

要实现宽字符(通常是`wchar_t`相关,如`CString`在`_UNICODE`编码下为宽字符)拷贝到`char`类型数据,可结合宽字符`char*`相互转换以及`char`型字符串安全拷贝的方法。 首先,可利用`CStringToCharArray`函数将宽字符的`CString`类型转换为`char*`类型,再使用`strlcpy`函数将转换后的`char*`数据安全地拷贝到目标`char`缓冲区。 以下是示例代码: ```cpp #include <iostream> #include <cstring> #include <atlstr.h> // 宽字符char*相互转换函数 char* CStringToCharArray(CString str) { char *ptr; #ifdef _UNICODE LONG len; len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL); ptr = new char [len+1]; memset(ptr,0,len + 1); WideCharToMultiByte(CP_ACP, 0, str, -1, ptr, len + 1, NULL, NULL); #else ptr = new char [str.GetAllocLength()+1]; sprintf(ptr,_T("%s"),str); #endif return ptr; } // char字符串更加安全的拷贝函数 strlcpy 实现方式 size_t strlcpy(char * dest, const char * src, size_t size) { char *d = dest; const char *s = src; size_t n = size; if (n != 0) { while (--n != 0) { if ((*d++ = *s++) == '\0') break; } } if (n == 0) { if (size != 0) *d = '\0'; while (*s++) ; } return(s - src - 1); } int main() { CString wideStr = L"宽字符示例"; char* convertedStr = CStringToCharArray(wideStr); char dest[100]; size_t result = strlcpy(dest, convertedStr, sizeof(dest)); std::cout << "拷贝后的 char 字符串: " << dest << std::endl; std::cout << "原始字符串长度: " << result << std::endl; delete[] convertedStr; return 0; } ``` 在上述代码中,`CStringToCharArray`函数把宽字符的`CString`转换为`char*`类型,`strlcpy`函数将转换后的`char*`数据安全地拷贝到`dest`缓冲区。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值