调试了2天,终于找到了答案。原因正是我太相信Qt的接口,QByteArray类提供了转换成char *的接口,可以这么转换:
QByteArray arr;
arr.toLatin1().data();
对于使用数量较少的数据,arr.toLatin1().data()可以直接作为参数传递,但对于安全性要求很严格的,就要考虑重新拷贝到自建的内存区域了(char *)。
【项目介绍】:
Windows服务端,该软件模拟登陆某个网站,抓取隐藏域,自动识别验证码,生成表单域并经过url编码,post给网站,实现模拟登陆。
【调试】:
昨天开始调试,发现验证码识别正确的,模拟登录失败,这问题让我很费解。终于,在使用了curl调试功能后(CURLOPT_DEBUGFUNCTION, CURLOPT_VERBOSE),真相大白了。结果竟然是http头的表单域不完整,如下:
Content-Type: application/x-www-form-urlencoded
后面没内容了。
有bug的代码:
bool CCurl::Post(const QString &actionUrl, const QString &fieldsInfo, QString &htmlStr)
{
//...
curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, fieldsInfo.toLatin1().data());
//...
return true;
}
bool CCurl::Post(const QString &actionUrl, const QString &fieldsInfo, QString &htmlStr)
{
//拷贝
int len = fieldsInfo.size();
char *buf = new char[len+1];
qMemCopy(buf, fieldsInfo.toLatin1().data(), len);
buf[len] = 0;
buf[fieldsInfo.size()] = 0;
//...
curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, fieldsInfo.toLatin1().data());
//...
delete [] buf;//释放
return true;
}