c - 可变参数宏包装器,可扩展为具有与参数数量对应的字符的格式字符串

标签 c c-preprocessor python-c-api variadic-macros

问题

我正在寻找一个可变参数 C 预处理器宏,它将其参数和相应的格式字符串传递给函数,并根据参数的数量重复一个字符。 例如,我想要一个宏 FOO,它扩展如下(或等效的 C 代码):

  • FOO(1)bar("d",1)
  • FOO(1,2)bar("dd",1,2),
  • FOO(1,2,3)bar("ddd",1,2,3)
  • 奖励:FOO()bar("")

虽然我可以将解决方案组合到 C preprocessor macro for returning a string repeated a certain number of timesC++ preprocessor __VA_ARGS__ number of arguments (或类似的问题)或使用 variadic macros ,这些有几个缺点,例如:

  • 需要特殊的库,例如 Boost(这对我来说是一个问题),
  • 依赖于编译器,
  • 仅在运行时工作,
  • 极其复杂。

我希望,当不单独考虑这些问题时,会出现一些更好的解决方案。

背景

我想在自动生成的代码中回调 Python C 扩展中的 Python 函数。 因此,例如,我需要 foo(1,2,3) 扩展为:

PyObject_CallObject( callback_foo, Py_Build_Value("(Oddd)",Y,1,2,3) )

我知道 foo 的所有参数都是 double ,但我不知道它们的数量。 (上面的示例有所简化。我知道它缺少一些 Py_DECREF。)

最佳答案

使用 100% 标准 C,您可以这样做:

#define COUNT_ARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
#define STRTABLE (const char*[]){ "", "d", "dd", "ddd", "ddddd" } // and so on
#define FOO(...) bar(STRTABLE[COUNT_ARGS(__VA_ARGS__)], __VA_ARGS__)

在此示例中,STRTABLE 是一个复合文字查找表,其中包含一堆字符串文字作为初始值设定项列表。通过计算宏参数的数量并专门使用该数组索引,仅使用与传递给宏的参数数量相对应的初始值设定项。

完整示例:

#include <stdio.h>

#define COUNT_ARGS(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
#define STRTABLE (const char*[]){ "", "d", "dd", "ddd", "ddddd" } // and so on
#define FOO(...) bar(STRTABLE[COUNT_ARGS(__VA_ARGS__)], __VA_ARGS__)

void bar(const char* fmt, ...)
{
  puts(fmt);
}

int main (void)
{
  FOO(1);
  FOO(1,2);
  FOO(1,2,3);
}

关于c - 可变参数宏包装器,可扩展为具有与参数数量对应的字符的格式字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60960579/

相关文章:

c# - 需要报价 : Preprocessor usage is bad OO practice

python - 在c中读取python的全局变量

python - 如何解决 AMD64 Win Python35_d.lib 中缺少 PyModule_Create2 的问题?

python - PyArg_ParseTupleAndKeywords 如何工作?

c - 没有从文件中获取 token ?

c - Openacc:如何使插入排序更加并行

64 位上的代码段错误也适用于 32 位

objective-c - self 关键字对于 C 结构体有什么特殊含义吗?

c++ - 在 C 和 C++ 中,为什么每个 .h 文件通常都用#ifndef#define #endif 指令包围?

c++ - 宏观评估顺序