最近为了采集视频中的图片,需要编写一个小程序以实现采样。本人采用的是VS2008运行编译代码,总会发现Error很相似,如下:
(1)MessageBox("Please stop the current video!");
error C2664:"MessageBoxW":不能将参数2从“const char[17]"转换为"LPCWSTR"
(2)static char Filter[] = "Available files (*.avi *.mpg)|*.avi;*.mpg|All Files (*.*)|*.*||";
CFileDialog fileDlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, Filter, NULL);
Error:不能将参数 5 从“const char [5]”转换为“LPCTSTR”
(3)CString FilePath;
m_capture = cvCaptureFromFile(FilePath);
Error C2664: “cvCreateFileCapture”: 不能将参数 1 从“CString”转换为“const char *”
以上代码编译出现错误的原因在于字符集,因为在VC6中,默认使用的是多字节字符集,不会出现这个问题,而VS2005以后的项目默认使用的是unicode字符集,在参数转换时会出错。
问题解决:
方法1:可将UNICODE字符集改为多字节字符集(在新建项目时,把使用UNICODE字符集取消;或者,选择“项目”-》“XXX项目属性”-》“配置属性”-》“常规”选项中,把“字符集”改为“使用多字节字符集”,然后确定),但是不推荐该方法。
对于Error(1):用两个宏TEXT或者_T可以解决这个问题,并无多大区别,TEXT由windows.h头文件 引入,而_T是通过tchar.h引入,推荐使用_T,修改如下:
MessageBox(_T("Please stop the current video!"));
对于Error(2):将文本内容放在_T()里面,不变字符集
CString Filter = _T("Available files (*.avi *.mpg)|*.avi;*.mpg|All Files (*.*)|*.*||");
对于Error(2): 查一下CString说明,将之转为char*,网上有人提议,采用CString的buffer方法,如下:
const char* filepath = FilePath.GetBuffer(sizeof(FilePath));
m_capture = cvCaptureFromFile(FilePath);
结果编译依然会出现错误。
后来冷推荐函数WideCharToMultiByte,UiCode下CString转char*,利用WideCharToMultiByte进行转换,解决了字符集编码的问题。
WideCharToMultiByte 函数功能:该函数映射一个unicode字符串到一个多字节字符串。
本人在网上找到了三种转换方法:
方法(一):使用函数setlocale
setlocale(LC_ALL,"chs"); 需要包含头文件#include<locale.h> //此方法的思路是配置地域化信息,通常在需要输入输出中文的时候设置一下,就没有问题了。
方法(二):使用函数:T2A, W2A
CString str = _T("D://校内项目//1.bmp");
USES_CONVERSION; // //声明标识符
char* pFileName = T2A(str); //调用函数,T2A和W2A均支持ATL和MFC中的字符转换
注意,有时候可能还需要添加引用#include <afxpriv.h>
方法(三):使用API:WideCharToMultiByte 进行转换
CString str = _T("D://校内项目//1.bmp");
// 注意:以下n和len的值大小不同,n是按字符计算的,len是按字节计算的
int n = str.GetLength(); // n = 14, len = 18
// 获取宽字节字符的大小,大小是按字节计算的
int len = WideCharToMultiByte(CP_ACP,0,str,str.GetLength(),NULL,0,NULL,NULL);
//为多字节字符数组申请空间,数组大小为按字节计算的宽字节大小
char* pFileName = new char[len + 1]; //以字节为单位
WideCharToMultiByte(CP_ACP,0,str,str.GetLength()+1,pFileName,len+1,NULL,NULL)
pFileName[len] = '\0' ; // 多字节字符以'\0'结束
所以,对于Error(3),程序代码修改如下:
CString FilePath;
int n = FilePath.GetLength();
// 获取宽字节字符的大小,大小是按字节计算的
int len = WideCharToMultiByte(CP_ACP, 0, FilePath, FilePath.GetLength(), NULL, 0, NULL, NULL);
char* pFilePath = new char[len + 1]; //为多字节字符数组申请空间,数组大小为按字节计算的宽字节大小,以字节为单位
WideCharToMultiByte(CP_ACP,0,FilePath,FilePath.GetLength()+1,pFilePath,len+1,NULL,NULL);
pFilePath[len] = '\0' ; // 多字节字符以'\0'结束
m_capture = cvCaptureFromFile(pFilePath);
最终运行成功了,花了N久的时间,^_^