Использование переменной для #define
Libcurl использует следующее для определения получателя электронной почты:
#define RECIPIENT "<bla@bla.com>"
Но что, если я не хочу жестко кодировать получателя? Я хочу, чтобы пользователь мог указать свой собственный адрес электронной почты, поэтому мне нужно найти способ сделать это:
std::string emailreceiver = "bla@bla.com";
#define RECIPIENT = emailreceiver
Получатель используется в этой строке:
rcpt_list = curl_slist_append(rcpt_list, RECIPIENT);
Я предполагаю, что я не могу просто изменить это на
std::string emailreceiver = "bla@bla.com";
rcpt_list = curl_slist_append(rcpt_list, emailreceiver);
У кого-нибудь есть предложения?
3 ответа
Curl ожидает строку C (const char *
), а не строка C++ (std::string
). Так что постарайтесь:
std::string emailreceiver = "bla@bla.com";
rcpt_list = curl_slist_append(rcpt_list, emailreceiver.c_str());
Там нет необходимости использовать #define
В общем, это был только пример.
Ваш последний фрагмент, вероятно, довольно близок. Судя по всему, curl ожидает строку в стиле C, поэтому вам, возможно, придется изменить ее на:
std::string emailreceiver = "bla@bla.com";
rcpt_list = curl_slist_append(rcpt_list, emailreceiver.c_str());
libcurl на самом деле этого не делает. #define
в вашем вопросе наиболее близко напоминает строку в docs/examples/smtp-multi.c
:
#define RECIPIENT "<recipient@example.com>"
Макрос используется ровно один раз, позже в том же исходном файле:
rcpt_list = curl_slist_append(rcpt_list, RECIPIENT);
(Цитируемые строки взяты из версии 7.23.0 curl.)
Как следует из названия файла, это только пример. В реальном приложении маловероятно, что вы захотите использовать встроенный макрос для имени получателя.
Декларация curl_slist_append
, в curl.h
, является:
CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *,
const char *);
(Не беспокойтесь о CURL_EXTERN
или const
теперь.)
Поэтому, когда вы звоните curl_slist_append
Второй аргумент должен быть char*
, В частности, это может быть строковый литерал, либо написанный непосредственно в вызове, либо полученный в результате расширения макроса. Но это может быть любое выражение типа char*
До тех пор, пока он указывает на правильную строку.
Вам нужно решить, как вы хотите определить адрес электронной почты получателя, и передать указатель на эту строку (строка в стиле C, а не C++ std::string
) как второй аргумент curl_slist_append
, Вероятно, не имеет смысла использовать макрос для этой цели. Для примера программы это был простой способ продемонстрировать, что происходит.
Что касается вашего вопроса в комментарии: "Мне все еще интересно, можно ли присвоить переменную #define или нет". - ну да и нет. Вы ничего не назначаете #define
, #define
(определение макроса) - это конструкция времени компиляции, которая вызывает замену любого вхождения имени макроса литеральным текстом определения макроса. Например, это:
#define RECIPIENT "<recipient@example.com>"
rcpt_list = curl_slist_append(rcpt_list, RECIPIENT);
в точности эквивалентно этому:
rcpt_list = curl_slist_append(rcpt_list, "<recipient@example.com>");
(кроме того, что последний не уходит RECIPIENT
определены). Если вы измените определение макроса с "<recipient@example.com>"
на что-нибудь еще, что вам нравится, то каждое вхождение RECIPIENT
будет заменено тем, что вы написали после #define RECIPIENT
,
Так что вы можете сделать что-то вроде этого:
char *recipient = get_recipient();
#define RECIPIENT recipient
rcpt_list = curl_slist_append(rcpt_list, RECIPIENT);
но в этом нет никакого смысла; Вы можете просто написать:
rcpt_list = curl_slist_append(rcpt_list, recipient);
Препроцессор (часть компилятора, который обрабатывает #define
директивы и расширения макросов, помимо прочего) абсолютно не имеют понятия о вызовах функций, переменных и подобных конструкциях. Это просто делает текстовую замену независимо от того, что означает текст. (Это на самом деле определяется в терминах токенов.)
Это означает, что вы можете злоупотреблять препроцессором для выполнения некоторых опасных действий. Вот пример.