Краткий ответ: я думаю, что вам нужно добавить содержимое в переменную получателей .
Вы не предоставили достаточно информации для изучения вашей реализации на С ++, поэтому мало что можно сказать по этому поводу. Я немного перевел ваш код обратно на C и подтвердил, что он работает так, как задумано, как в примере cURL smtp-mail.c.
soquestsmtp-mail.cpp
#include "pch.h"
enum optionuses : uint32_t
{
useVerboseOutput = 1 << 1, // 0x02
useTLS = 1 << 2, // 0x04
useAuthentication = 1 << 3, // 0x08
};
struct upload_status {
int lines_read;
};
typedef struct upload_status* pupload_status;
static size_t __cdecl invoke_write_data(void* buffer, size_t size, size_t nmemb, void* pInstance);
static size_t __cdecl payload_source(void* buffer, size_t size, size_t nmemb);
static size_t __cdecl read_callback(void* buffer, size_t size, size_t nitems, void* instream);
static const char* payload_text[] = {
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",
"To: <addressee@example.net>\r\n",
"From: <sender@example.org>\r\n",
"Cc: <info@example.org>\r\n",
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@"
"rfcpedant.example.org>\r\n",
"Subject: SMTP example message\r\n",
"\r\n", /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n",
"\r\n",
"It could be a lot of lines, could be MIME encoded, whatever.\r\n",
"Check RFC5322.\r\n",
nullptr
};
extern "C" int __cdecl
wmain(_In_ int argc,_In_reads_(argc) _Pre_z_ wchar_t** argv,_In_z_ wchar_t** envp)
{
argc;argv;envp;
CURL* curl = nullptr;
int res = CURLE_OK;
uint32_t options = useVerboseOutput|useTLS|useAuthentication;
std::string smtpAddress = "smtp://mail.example.com";
std::string fromAddress = "<sender@example.org>";
std::string toAddress = "<addressee@example.net>";
std::string ccAddress = "<info@example.org>";
std::string username = "sockerconny";
std::string password = "love_mom";
struct curl_slist* recipients = nullptr;
struct upload_status upload_ctx;
upload_ctx.lines_read = 0;
curl = curl_easy_init();
//curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1);
if (curl)
{
if (options & useVerboseOutput)
{
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
}
curl_easy_setopt(curl, CURLOPT_URL, smtpAddress.c_str());
if (options & useTLS)
{
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
}
if (options & useAuthentication)
{
if (username.empty() || password.empty())
{
// throw std::logic_error("SMTP username or password has not been set but authentication is enabled");
}
curl_easy_setopt(curl, CURLOPT_USERNAME, username.c_str());
curl_easy_setopt(curl, CURLOPT_PASSWORD, password.c_str());
}
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, fromAddress.c_str());
recipients = curl_slist_append(recipients, toAddress.c_str());
recipients = curl_slist_append(recipients, ccAddress.c_str());
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
//Send the message
res = curl_easy_perform(curl);
curl_slist_free_all(recipients);
curl_easy_cleanup(curl);
}
}
size_t __cdecl read_callback(void* buffer, size_t size, size_t nitems, void *instream)
{
pupload_status pupload_ctx = (pupload_status)instream;
const char* data = nullptr;
if((size == 0) || (nitems == 0) || ((size*nitems) < 1)) {
return 0;
}
data = payload_text[pupload_ctx->lines_read];
if(data) {
size_t len = strlen(data);
memcpy(buffer, data, len);
pupload_ctx->lines_read++;
return len;
}
return 0;
}
pch.h
// pch.h - precompiled header with standard includes and definitions
#pragma once
#define STRICT
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#define DISABLE_WARNING_PUSH(x) \
__pragma(warning(push)); __pragma(warning(disable: x))
#define DISABLE_WARNING_POP __pragma(warning(pop))
#define _WIN32_WINNT 0x0601 // minimum Windows 7
#include <winsdkver.h>
#include <sdkddkver.h>
#ifndef WINAPI_FAMILY
#define WINAPI_FAMILY WINAPI_FAMILY_DESKTOP_APP
#endif
// disable useless MSVC warnings when compiling with -Wall
#pragma warning(disable: 4514 4710 4711)
// comment out for diagnostic messages, usually safe to ignore
#pragma warning(disable: 4625 4626 4820)
// temporary disable warnings when compiling with -Wall
DISABLE_WARNING_PUSH(4191 4350 4365 4774 4571 4640 5026 5027 5039)
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include <stdexcept>
#include <windows.h>
#include <ws2tcpip.h>
DISABLE_WARNING_POP
#define CURL_STATICLIB
#define USE_LIBSSH2
#define HAVE_LIBSSH2_H
#define USE_SCHANNEL
#define USE_WINDOWS_SSPI
#define USE_WIN32_IDN
#define WANT_IDN_PROTOTYPES
#include <curl/curl.h>