简体   繁体   English

如何将C宏的某些参数定义为另一个宏?

[英]How can I define some arguments of a C macro as another macro?

Consider the macro 考虑宏

#define IP4_ADDR(ipaddr, a,b,c,d)  (ipaddr)->addr = PP_HTONL(LWIP_MAKEU32(a,b,c,d))

I would like to define the arguments a,b,c,d in another macro. 我想在另一个宏中定义参数a,b,c,d。 So I have done this: 所以我做到了:

#define DEBUG_HOST_IP4 192, 168, 0, 123

IP4_ADDR(&debug_host, 192, 168, 0, 123 );
IP4_ADDR(&debug_host, DEBUG_HOST_IP4 );

The first call to IP4_ADDR compiles succesfully, while the second one fails with 对IP4_ADDR的第一次调用成功编译,而第二次调用失败

error: macro "IP4_ADDR" requires 5 arguments, but only 2 given 错误:宏“ IP4_ADDR”需要5个参数,但仅提供2个
IP4_ADDR(&debug_host, DEBUG_HOST_IP4 ); IP4_ADDR(&debug_host,DEBUG_HOST_IP4);

Is there a way to make DEBUG_HOST_IP4 expand properly, so the IP4_ADDR macro can work as intended? 有没有办法使DEBUG_HOST_IP4正确扩展,以便IP4_ADDR宏可以按预期工作?

EDIT: The IP4_ADDR macro comes from a third-party library, which I would rather not touch, and risk breaking somebody else's code. 编辑:IP4_ADDR宏来自第三方库,我宁愿不接触它,并且有可能破坏别人的代码。 Of course, implementing my own version is an option. 当然,实现我自己的版本是一种选择。

In this case, you can make your outer macro a varargs macro: 在这种情况下,可以使外部宏成为varargs宏:

#define IP4_ADDR(ipaddr, ...)  (ipaddr)->addr = PP_HTONL(LWIP_MAKEU32(__VA_ARGS__))

The macro invocation must have the correct number of arguments. 宏调用必须具有正确数量的参数。 The inner macro invocation works because arguments are expanded before the body is rescanned. 内部宏调用之所以有效,是因为在重新扫描正文之前先扩展了参数。

The varargs syntax allows you to either supply the four arguments or use a macro which expands to them. varargs语法允许您提供四个参数或使用扩展为它们的宏。

If you don't want to alter the definition of IP_ADDR , you invoke it indirectly through a wrapper macro: 如果您不想更改IP_ADDR的定义,则可以通过包装宏间接调用它:

#define CALL(macro, __VA_ARGS__) macro(...)
// ...
CALL(IP4_ADDR, &debug_host, DEBUG_HOST_IP4 );

Try to define like this: 尝试这样定义:

#define IP4_ADDR(ipaddr, HOST)  (ipaddr)->addr = PP_HTONL(LWIP_MAKEU32(HOST))

DEGUB_HOST_IP4 will be replaced only in second part. DEGUB_HOST_IP4将仅在第二部分中被替换。 So when you passed it as parameter, it was replaced only to a, and b, c, d was ignored 因此,当您将其作为参数传递时,它仅替换为a,而b,c,d被忽略

If you can't alter IP4_ADDR, this is still pretty easy; 如果您不能更改IP4_ADDR,这仍然很容易。 just wrap it: 包裹一下:

#define MY_IP4_ADDR(...) IP4_ADDR(__VA_ARGS__)

During the translation (which just moves all of the arguments over, whatever they are), any macros will expand. 在翻译过程中(将所有参数移至任何位置),所有宏都会扩展。 Then just use your wrapped version in the code. 然后,只需在代码中使用包装的版本即可。

  MY_IP4_ADDR(&debug_host, 192, 168, 0, 123 );
  MY_IP4_ADDR(&debug_host, DEBUG_HOST_IP4 );

And you should be good to go. 而且您应该很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM