200分请VC++编程高手进。。。请教编译错误问题。。。。

BOOLCBlockingSocketException::GetErrorMessage(LPTSTRlpstrError,UINTnMaxError,PUINTpnH... BOOL CBlockingSocketException::GetErrorMessage(LPTSTR lpstrError, UINT nMaxError,PUINT pnHelpContext /*= NULL*/)
{
char text[200];
if(m_nError == 0)
{
wsprintf(text, "%s error", (const char*) m_strMessage);
}
else {
wsprintf(text, "%s error #%d", (const char*) m_strMessage, m_nError);
}
strncpy(lpstrError, text, nMaxError - 1);
return TRUE;
}

error C2440: 'type cast' : cannot convert from 'class CString' to 'const char *'
error C2664: 'wsprintfW' : cannot convert parameter 1 from 'char [200]' to 'unsigned short *'
error C2440: 'type cast' : cannot convert from 'class CString' to 'const char *'

error C2664: 'wsprintfW' : cannot convert parameter 1 from 'char [200]' to 'unsigned short *'

error C2664: 'strncpy' : cannot convert parameter 1 from 'unsigned short *' to 'char *'

以上错在哪里?如何改?
展开
 我来答
yi...9@126.com
2010-05-11 · TA获得超过887个赞
知道小有建树答主
回答量:405
采纳率:0%
帮助的人:285万
展开全部
VC真是一个非常笨,非常不友好的工具,还是这样说,VC(MFC)和现在流行的。net framework java比起来就想石器时代跟工业时代相比一样

WC_DEFAULTCHAR, strWideChar, strWideChar.GetLength(), (char *)buf, //转换到缓冲区中 20, //最多个字节 0, 0 );

同样的,你接收到的字符串想要在界面正常显示,还必须把它转换成宽字节表示:

char chBytes[8]; memcpy(chBytes,”aaaaaaa\0”,8); WCHAR wch[9]; n = MultiByteToWideChar( //转换Unicode到Ansi CP_ACP, 0, chBytes, 8, wch, //转换到缓冲区中 8 //最多个字节 ); wch[n] = ‘\0‘;

这样每次从界面取数据和把数据显示到界面上都要先做处理,但是也可以把编译环境设置成“多字符集”(Multi-Byte Character Set),就可以避免这样转换来转换去(可惜我发现的时候代码已经差不多写完了)。就是在“Project-Configuration Properties-General-Character Set,选择”Use Unicode Character Set“就是使用Uncode字符集,选择” Use Multi-Byte Character Set“就是多字节字符集。

第二次中招,god,花了我好长时间才找到问题:

我在CodeProject上找了一个很厚道的老外写的一个继承了CDialog窗体类CResizableDialog的源码,这个类的作用是使MFC的窗体放大缩小时,窗体上的控件可以定位(Auchor),不要小看这个小小的每天都要用到的功能,用MFC实现真的很麻烦。很佩服那个老外写了那么多代码(当然跟他们的条件有关,资本主义国家的工人随便找个工作就可以衣食无忧,病了政府照顾,我们做“挨踢”的活得像民工一样,当然没有那个闲情去写那么好的代码免费给别人使用,这是题外话)。

我拿了那个现成的工程,直接在我的工程里引用他的工程。Everything works perfect.直到我把项目发布成Release的,双击运行后没有任何反应,Very weird!后来我用MessageBox打印消息,发现运行到DoModal函数里面就没有出来,程序直接退出了!使用try,catch都得不到错误!因为我的窗体是继承老外写的窗体类来的,原先继承CDialog是好好的,问题肯定在他的工程里面,可是他给的示例程序没有任何问题啊。MFC出错的时候是很要命的,它不会给你任何提示,它就是不干了!

我又拿一个前的测试程序,让它从CResizableDialog继承,也没有任何问题。

简直头大了、无语了,不知道哪里出现了问题,Release又不能像Debug那样调试,打了一堆MessageBox后还是不知道问题出现在哪里。凭着经验,可以知道程序中可能出现了内存的越界访问什么的致命错误,才会导致程序“一声不吭”地退出,但是究竟哪里出了问题呢?

就在束手无策的时候,我发现调用CResizableDialog的成员函数EnableSaveRestore会引发链接错误:“未定义的外部符号”,不引用它不会出错,测试程序引用它没有任何错误。通常这个错误造成是因为引用函数在。h文件里声明了,但是在。cpp里面没有定义,或者。cpp文件里的定义和。h上的参数对不上。但是此时不可能是这个错误,因为测试程序没有错误啊。直觉告诉我这是解决“Release后程序直接退出的关键”,说不定这个函数调用的问题解决了Release的问题也解决了。

MFC真是很强大,它强大得不但“像迷宫一样,里面有怪兽,进去一不小心就永远出不来”,而且它让你当遇到怪兽的时候总是给你一点点星光,只要你不放弃,奇迹就会出现,你就会练成绝世神功。这跟武侠小说是相通的,主人公每次到了生死关头就会出现奇迹,成为天下无敌的高手。看看我怎么找到解决方法的,Very tricky。

既然调用EnableSaveRestore出现了不该出现的错误,那么就从这个函数开始找。这个函数是这样的:

.h文件声明 void EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly = FALSE); .cpp文件定义 void CResizableDialog::EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly/* = FALSE */) { m_sSection = pszSection; m_bEnableSaveRestore = TRUE; m_bRectOnly = bRectOnly; // restore immediately LoadWindowRect(pszSection, bRectOnly); }

上面的代码没有任何错误,既然没有错误,就要用使用以下方法来找:

1.重新为CResizableDialog写一个函数,它没有参数的,调用它,发现没有错误,看来参数有问题。

2.既然没有参数的函数没有错误,就把出问题的函数参数去掉吧,竟然也没有错误!那问题就肯定是出在参数上。

3.去掉其中一个参数,测试发现是LPCTSTR pszSection的问题,而不是BOOL bRectOnly的问题。

4.既然这样,那就换一种表示吧,把LPCTSTR pszSection换成WCHAR* pszSection,运行它,竟然不出错了!翻开MFC宏定义,就会发现其实LPCTSTR和WCHAR*是一样的,MFC真是freak!

5.但是这个函数功能还是不正常,断点进入那个函数里面发现传进去的字符串只有一个字符了,这种情况就是宽字符当成短字符时,第二个字节的\0当成了字符串的截止字符了,也就是说,这个函数里采用的是短字符(多字符集Multi Byte)处理的。

6.我的工程采用的是宽字符集(Unicode Char)的,检查设置,原来那个老外是用VC6编的,默认是使用多字符集(Multi Byte)的,VC真是笨啊,两个Project在一个Solution里面完全不同的设置竟然没有任何提示,简直把我弄死了!

7.把引用工程也改成使用Unicode字符集,并且把函数EnableSaveRestore WCHAR* pszSection恢复原样,搞定!果然不出我所料,Release也没有问题了!我用以前的那个测试程序来使刚好以前把它设成Multi Byte,所以也没有错误,Damn!

仅仅是一个设置啊,如果VC出错提示稍微好的,至少字符集不匹配不要说成“未定义的外部符号”也好用一点啊,难怪现在用VC的人越来越少了!

注:通常说的VC不是指使用。net framework的VC,那个很简单,内存都不用管,通常是指非托管的VC。
诛神诛仙
2010-05-11 · TA获得超过278个赞
知道小有建树答主
回答量:188
采纳率:0%
帮助的人:0
展开全部
char text[200];
if(m_nError == 0)
{
wsprintf(text, "%s error", m_strMessage);//这里1
}
else {
wsprintf(text, "%s error #%d", (const char*) m_strMessage, m_nError);
}
strncpy((char*)lpstrError, text, nMaxError - 1);//这里2
return TRUE;

wsprintf:这个函数第二个参数是LPCTSTR 类型的,不是const char*类型的,你为啥要把CString的m_strMessage变量转化成const char*呢?
再说了m_strMessage是CString类型的,是不能转化成const char*的,m_strMessage又不是一个指针型的变量,你想转化成指针型的话,它有个取地址的函数,可以直接引用赋值给char*的指针变量,而不能赋值给const char*的指针变量。
const char*的指针只能获得const类型变量的指针,而不是指向非const类型的变量或者指针。你一定要好好的把这个关系搞清楚。
建议你首先看下wsprintf这个API的用法,仔细的看下,然后再复习一下CString和LPCTSTR是如何转化的(实际上可以直接赋值),再看一下char* 和LPCTSTR和CString是如何相互转化的。
对于第2个,strncpy两个参数都需要char*类型,强制转化一下就好。
如果还有问题,上Hi然后聊。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
_小_苏
2010-05-11 · TA获得超过343个赞
知道小有建树答主
回答量:330
采纳率:100%
帮助的人:210万
展开全部
你的参数类型不对。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友b3c8429
2010-05-11 · 超过25用户采纳过TA的回答
知道答主
回答量:146
采纳率:0%
帮助的人:88.2万
展开全部
char text[200];这里的问题
char 类型不匹配
改为string text;
下面也要改
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友5803c9a
2010-05-11 · TA获得超过2162个赞
知道小有建树答主
回答量:891
采纳率:0%
帮助的人:1223万
展开全部
BOOL CBlockingSocketException::GetErrorMessage(LPTSTR lpstrError, UINT nMaxError,PUINT pnHelpContext /*= NULL*/)
{
CString text;
if(m_nError == 0)
{
wsprintf(text, "%s error", m_strMessage.GetBuffer());
}
else {
wsprintf(text, "%s error #%d", m_strMessage.GetBuffer(), m_nError);
}
wcsncpy_s(lpstrError, text, nMaxError - 1);
return TRUE;
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
epldlnwynn
2010-05-11 · TA获得超过149个赞
知道小有建树答主
回答量:192
采纳率:0%
帮助的人:153万
展开全部
很明显,都是说char引起 的, 你应该关注“(const char*) m_strMessage”里。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(6)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式