【发布时间】:2018-12-11 02:16:51
【问题描述】:
我正在开发一个 C++ 项目,我正在使用 libcurl 通过 SMTP 发送电子邮件。该代码几乎适用于小内容,但是,在较大的电子邮件中,它会引发写访问冲突,我看不出任何原因。
以下是我如何使用 curl 功能发送邮件:
curl = curl_easy_init();
//curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1);
if (curl)
{
if (this->useVerboseOutput)
{
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
}
curl_easy_setopt(curl, CURLOPT_URL, smtpAddress.c_str());
if (this->useTLS)
{
curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
}
if (this->useAuthentication)
{
if (this->username.empty() || this->password.empty())
{
throw logic_error("SMTP username or password has not been set but authentication is enabled");
}
curl_easy_setopt(curl, CURLOPT_USERNAME, this->username.c_str());
curl_easy_setopt(curl, CURLOPT_PASSWORD, this->password.c_str());
}
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, this->fromAddress.c_str());
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
curl_easy_setopt(curl, CURLOPT_READDATA, this);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, &EmailSender::invoke_write_data);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
//Send the message
res = curl_easy_perform(curl);
下面是read函数回调
size_t EmailSender::invoke_write_data(void *data, size_t size, size_t nmemb, void* pInstance)
{
return ((EmailSender*)pInstance)->payload_source(data, size, nmemb);
}
size_t EmailSender::payload_source(void *ptr, size_t size, size_t nmemb)
{
//struct upload_status *upload_ctx = (struct upload_status*)userp;
const char *data;
if ((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
return 0;
}
if (this->upload_ctx.lines_read < this->lineArray.size())
{
data = this->lineArray.at(this->upload_ctx.lines_read).c_str();
}
else
{
return 0;
}
if (data) {
size_t len = strlen(data);
memcpy(ptr, data, len);
this->upload_ctx.lines_read++;
return len;
}
return 0;
}
在第 5 次调用后,它在this->upload_ctx.lines_read++; 线上崩溃(向量 lineArray 中有 6 行,upload_ctx->lines_read 为 5。
完整的错误信息是:
Exception thrown at 0x00007FFF4E8F16D7 (vcruntime140d.dll) in myapp.exe: 0xC0000005: Access violation writing location 0x00000205CC8AC000.
【问题讨论】:
-
正如您在代码中看到的,我有一个静态方法,由 libcurl 读取函数调用,然后将 userp 指针转换回类实例以调用我的函数来完成工作。如果它与此相关,它将不适用于任何请求,而不仅仅是大请求会有问题