mlfiPriv * MLFIPRIV (SMFICTX *ctx)
{
return (mlfiPriv *) smfi_getpriv(ctx);
}
указатели в sendmail milter
Хочу разобраться с milter sendmail начал читать пример котрый приведен с исходным кодом, там есть такие строки
struct mlfiPriv // это понятно что объявляется структура.
{
char *mlfi_fname;
FILE *mlfi_fp;
};
// А вот тут не могу разобраться
#define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx))
Может кто подскажет ???
Директива #define заменяет все появления "идентификатор" в исходном файле на "текст-замены". Идентификатор заменяется только тогда, когда он формирует лексему. Например, идентификатор не будет заменен, если он появляется в строке или как часть более длинного идентификатора.
понятно. А эту чать как понять ((struct mlfiPriv *) smfi_getpriv(ctx)) ?
Ну, просто все слова MLFIPRIV заменяются на ((struct mlfiPriv *) smfi_getpriv(ctx)), а что это означает в конкретном случае, я понятия не имею.
Это обычный макрос. Я так понимаю, автор использует пример, подобный этому - http://www.sendmail.org/doc/sendmail-current/libmilter/docs/sample.html. Читаем описание функции smfi_getpriv.
Цитата:
SYNOPSIS #include <libmilter/mfapi.h>
void* smfi_getpriv(
SMFICTX *ctx
);
Get the connection-specific data pointer for this connection.
DESCRIPTION Called When smfi_getpriv may be called in any of the xxfi_* callbacks.
Effects None.
ARGUMENTS Argument Description
ctx Opaque context structure.
RETURN VALUES smfi_getpriv returns the private data pointer stored by a prior call to smfi_setpriv, or NULL if none has been set.
Сравнивая сигнатуру функции с определением макроса, понимаем - функция возвращает неудобный тип void *. И нам бы пришлось все время явно приводить его к нужному типу в каждом конкретном случае. Но раз мы используем эту функцию только для получения структуры mlfiPriv *, то мы пишем макрос, выполняющий нужный даункастинг, и в дальнейшем пользуемся не "сырой" функцией, а макросом - оболочкой.
C не меньшим успехом мы могли бы написать функцию-оболочку ("wrapper") вида:
Код:
Но автор примера использут C-style, предпочитая макросы. Однако лучше везде, где возможно, заменять макросы функциями (IMHO).