如何在 C 中包装可变参数函数

How to wrap a variadic function in C

我正在尝试包装可变参数函数以预先验证输入。准确地说,我需要调用 sd_notifyf(int unset_environment, const char *format, ...).

https://www.freedesktop.org/software/systemd/man/sd_notify.html

但在调用 sd_notifyf 之前,我想验证格式的输入,然后在包装函数中调用 sd_notify()。

目前我尝试了以下方法:

void wrapperFunc(int unset_environment, const char *format, ...) {
  va_list list;
  va_start(list, format);

  //validation of va_args

  sd_notifyf(unset_environment, format, list);

  va_end(list);
}

int main(int argc, char *argv[]) {
  wrapperFunc(0, "STATUS=args: '%s' : '%s'", "arg1", "arg2");
}

在实际代码中,wrapperFunc() 会在启动服务时被调用,所以你可以理解我为什么要调用 sd_notifyf()。

在我当前的实现中,检查服务状态时会返回以下内容: STATUS=args: '^P' : 'arg2'

为什么它只正确显示第二个参数?我怎样才能正确包装 sd_notifyf()?

您的代码的行为未定义。

sd_notifyf 是可变参数函数,而不是将 va_list

作为最后一个参数的函数
int sd_notifyf( int unset_environment,
    const char *format,
    …);

恐怕您无法编写包装函数,因为没有采用 va_list

sd_notify 函数版本

您只能为此使用宏定义。

#define wrapperMacro(unset_environment, format, ...)\
    do{\
        /* do some stuff */\
         sd_notifyf(unset_environment, format, __VA_ARGS__);\
    }while(0)

您还可以使用字符串 printf 函数(在本例中 vsnprintf):

#define LARGE_ENOUGH_TO_ACCOMODATE_THE_STRING 64

void wrapperFunc(int unset_environment, const char *format, ...) {
  va_list list;
  va_start(list, format);
  char buff[LARGE_ENOUGH_TO_ACCOMODATE_THE_STRING];

  vsnprintf(buff, sizeof(buff), format, list);

  sd_notify(unset_environment, buff);

  va_end(list);
}