如何在C中的宏中多次调用函数?

如何在C中的宏中多次调用函数?,c,macros,C,Macros,在我的开发环境中,一些ioctl调用在第一次调用时失败,如果我再次调用相同的ioctl,则返回成功。 这是因为一些与硬件相关的时间同步问题 所以我们要寻找一些临时解决方案,比如用一个宏来屏蔽所有ioctl,在宏中调用ioctl三次 但该宏抛出编译错误。请提出一些解决此问题的解决方案 示例代码 #include <stdio.h> int func (int a, int b, int c) { return -1; } #define IOCTL_WRAPPER(a,b,

在我的开发环境中,一些
ioctl
调用在第一次调用时失败,如果我再次调用相同的
ioctl
,则返回成功。
这是因为一些与硬件相关的时间同步问题

所以我们要寻找一些临时解决方案,比如用一个
宏来屏蔽所有
ioctl
,在
宏中调用
ioctl
三次

但该
抛出编译错误。请提出一些解决此问题的解决方案

示例代码

#include <stdio.h>

int func (int a, int b, int c)
{
    return -1;
}

#define IOCTL_WRAPPER(a,b,c)                    \
            {                                   \
                int i = 0, retval = 0;          \
                while (i < 3)                   \
                {                               \
                    retval = func (a, b, c);    \
                    if (retval != -1)           \
                    {                           \
                        break;                  \
                    }                           \
                    i++;                        \
                }                               \
                retval;                         \
            }

int main ()
{
    int RetVal = 0;

    RetVal = IOCTL_WRAPPER(1, 2, 3);

    if (RetVal != -1)
    {
        printf ("\n pass \n");
    }
    else
    {
        printf ("\n fail \n");
    }

    return 0;
}

宏扩展为代码块,该代码块不是表达式

为什么不直接使用内联函数呢?示例代码:

static inline int ioctl_wrapper(int a, int b, int c)
{
    int i = 0, retval = 0;
    while (i < 3)
    {
        retval = func (a, b, c);
        if (retval != -1)
        {
            break;
        }
        i++;
    }
    return retval;
}

如果三个调用之一的返回值不是-1,
retval
将是1;否则,它将为0。

我建议使用
do while
宏样式以避免将来出现问题。要解决您的问题,请将retVal作为参数:

#define IOCTL_WRAPPER(retval, a,b,c)        \
        do {                                \
            int i = 0;                      \
            while (i < 3)                   \
            {                               \
                retval = func (a, b, c);    \
                if (retval != -1)           \
                {                           \
                    break;                  \
                }                           \
                i++;                        \
            }                               \
        } while(0)

我们不能将函数用于此目的,因为同时访问ioctl调用可能会导致问题。Hakkim,这种评论没有意义。如果使用函数可以同时访问ioctl调用,那么宏也可以。语句只能在函数中执行。@HakkimAnsari为什么需要宏?为什么你不能把它包装成一个普通函数?你的评论真的没有意义。这在我看来像是一个错误。你的
IOCTL\u包装器
宏实际上包装了
func
,而不是
IOCTL
,这有点奇怪。这是在创建问题时改变了主意,还是表明您有一个指向调用
ioctl
的函数的指针?问题是否可能是多线程修改函数指针?“硬件相关的时间同步问题”--仲裁对设备的安全并发访问是
ioctl()
后面的操作系统中的代码的责任。你应该在那里提出解决这个问题的理由。是的,我知道这可能超出了您的职责范围,但这是提供修复的最合适的地方。为什么
extern
而不是
static
?我会使用
static
,但决不会使用
extern
和内联函数。@JonathanLeffler似乎
extern
static
都可以。看:从句法上说,是的。您理解
extern
的语义吗?这不是直截了当的。@JonathanLeffler我不确定。。。事实上,我从未编写过任何分布在多个文件中的C代码。也许你可以给我提供一些阅读资料?你已经得到了我将提供的外部参照(你链接到了它),或者在这个主题上可能还有另一个类似的问题。您不必更改答案,但如果您将
静态
内联
一起使用,您的生活可能会更简单-您不必担心多个(可见)定义会破坏链接。
retval = (func(a, b, c) + 1) || (func(a, b, c) + 1) || (func(a, b, c) + 1);
#define IOCTL_WRAPPER(retval, a,b,c)        \
        do {                                \
            int i = 0;                      \
            while (i < 3)                   \
            {                               \
                retval = func (a, b, c);    \
                if (retval != -1)           \
                {                           \
                    break;                  \
                }                           \
                i++;                        \
            }                               \
        } while(0)
IOCTL_WRAPPER(RetVal, 1, 2, 3);