【问题标题】:How to wrap a variadic function in C如何在 C 中包装可变参数函数
【发布时间】:2022-01-17 13:01:31
【问题描述】:

我正在尝试包装一个可变参数函数来预先验证输入。准确地说,我需要调用 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() ?

【问题讨论】:

  • Sooo,你听说过snprintf吗?还是更好的aprintfvsnprintfvasprintf?然后拨打sd_notify
  • 当你说“为什么它只正确显示第二个参数?”你实际上得到了什么?
  • @KamilCuk 不是真的,这是我第一次使用可变参数函数,所以我还在学习。您能否提供一个小例子,我如何使用 vsnprintf 实现这一目标?
  • @Andrew 我在帖子中包含的输出,第一个参数总是减少到 '^P' 而第二个是正确的,不知道如何调试 sd_notifyf 的输出所以我不知道为什么我收到第一个 arg 的 '^P'

标签: c variadic-functions systemd variadic


【解决方案1】:

您的代码行为未定义。

sd_notifyf 是可变参数函数,不是以va_list为最后一个参数的函数

int sd_notifyf( int unset_environment,
    const char *format,
    …);

恐怕您不能编写包装函数,因为没有采用va_listsd_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);
}

【讨论】:

  • @EricPostpischil args 对我来说是一个明显的错字。否则,整个问题毫无意义。
  • @EricPostpischil args 而不是 list
  • @EricPostpischil 这确实是一个错字,当然是要通过列表... :)
  • @Xershy 所以编辑你的问题
猜你喜欢
  • 1970-01-01
  • 2023-03-14
  • 2022-11-05
  • 2010-09-07
  • 2019-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
相关资源
最近更新 更多