考虑宏
#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->addr = PP_HTONL(LWIP_MAKEU32(a,b,c,d))
我想在另一个宏中定义参数a,b,c,d。所以我做到了:
#define DEBUG_HOST_IP4 192, 168, 0, 123
IP4_ADDR(&debug_host, 192, 168, 0, 123 );
IP4_ADDR(&debug_host, DEBUG_HOST_IP4 );
对IP4_ADDR的第一次调用成功编译,而第二次调用失败,
错误:宏“ IP4_ADDR”需要5个参数,但仅提供2个
IP4_ADDR(&debug_host,DEBUG_HOST_IP4);
是否有一种方法可以使DEBUG_HOST_IP4
正确展开,以便IP4_ADDR
宏可以按预期工作?
编辑:IP4_ADDR宏来自第三方库,我不希望接触它,并且可能会破坏其他人的代码。当然,实现我自己的版本是一种选择。
答案 0 :(得分:3)
在这种情况下,您可以将外部宏设为varargs宏:
#define IP4_ADDR(ipaddr, ...) (ipaddr)->addr = PP_HTONL(LWIP_MAKEU32(__VA_ARGS__))
宏调用必须具有正确数量的参数。内部宏调用之所以有效,是因为在重新扫描正文之前先扩展了参数。
varargs语法允许您提供四个参数或使用扩展为它们的宏。
如果您不想更改IP_ADDR
的定义,则可以通过包装宏间接调用它:
#define CALL(macro, __VA_ARGS__) macro(...)
// ...
CALL(IP4_ADDR, &debug_host, DEBUG_HOST_IP4 );
答案 1 :(得分:1)
尝试这样定义:
#define IP4_ADDR(ipaddr, HOST) (ipaddr)->addr = PP_HTONL(LWIP_MAKEU32(HOST))
DEGUB_HOST_IP4仅在第二部分中被替换。因此,当您将其作为参数传递时,它仅被替换为a,而b,c,d被忽略了
答案 2 :(得分:1)
如果您不能更改IP4_ADDR,这仍然很容易;包裹一下:
#define MY_IP4_ADDR(...) IP4_ADDR(__VA_ARGS__)
在翻译期间(它将所有参数移至任何位置),所有宏都会扩展。然后只需在代码中使用包装的版本即可。
MY_IP4_ADDR(&debug_host, 192, 168, 0, 123 );
MY_IP4_ADDR(&debug_host, DEBUG_HOST_IP4 );
你应该很好。