【问题标题】:passing function with variable parameter as void pointer, and calling it将带有可变参数的函数作为 void 指针传递,并调用它
【发布时间】:2013-02-20 07:01:47
【问题描述】:

我有一个函数,我想通过各种函数

int func1(char *ptr)
{
    printf("%s",ptr);
    return 0;
}

和我想在其中调用 func1 的其他函数

int func2(void *i)
{
    //call i
    //here i point to function func1
    //and do something with return value of i
}

那么,我应该如何在 main() 中调用它?

int main()
{
    void *d;
    //SOMETHING wrong in next four line
    d=&func1("abcd");
    func2(d);
    d=&func1("xyz");
    func2(d);
    return 0;
}

【问题讨论】:

  • 您需要使用函数指针才能做到这一点。 main 也没有 void * 参数。
  • 抱歉没有在 main 中使用 void *i 所以删除了它
  • @gauravmeena d = &func1("abcd");可能不起作用,因为 func1("abcd") 将给出 func1 返回的数据(根本没有)而不是 func1 的地址..
  • 是的...我知道,但我写它只是为了解释我想要做什么

标签: c pointers


【解决方案1】:

您可以简单地创建一个函数 (func2),该函数将一个函数指针指向您想要调用的所需函数,另一个参数将指向您的字符串的指针。然后在func2 中使用str 参数调用传入的函数指针。

#include <stdio.h>

void func1(const char *str)
{
    puts(str);
}

void func2(void (*fp)(const char *), const char *str)
{
    fp(str);
}

int main(void)
{
    const char *str = "Hello world.";

    func2(func1, str);

    return 0;
}

【讨论】:

  • @kludas 是的,这是最合适的方式。但我看到一个 gauravmeena 的 cmets func2 是一个 lib 函数,并且只允许使用 void 指针。您还可以传递一个带有函数指针和字符串(作为 char *)作为成员的结构,并将其重铸回 func2 中的结构?
  • @Koushik 是的,这是对我的限制,但是在您的回答中,您将字符串放入 func2 .... Kludas 也可以这样做,并使用一个参数作为输入来制作 func2。从 main 传递字符串的唯一方法是按照您的建议使用 struct
  • @gaurav 在我的回答中,func2 参数是 void *,func1 有 char *。是的 struct 更合适,因为您无法更改 func2 定义。如果它设计正确,那么我想它本身会期待一个结构。
【解决方案2】:

首先:函数指针只引用一个函数。直接或通过函数指针调用函数时,参数进入游戏。

因此,如果您想实现您的想法,即将(一组)参数绑定到特定的函数变量,您需要使用包装函数:

int func1(char * pc)
{
  int i;
  /* assigne somehting to "i" and use "pc" */
  return i;
}

int func1_abcd(void)
{
  return func1("abcd")
}

int func1_xyz(void)
{
  return func1("xyz")
}

typedef int (*pfunc1_wrapper_t)(void);

int func2(pfunc1_wrapper_t pfunc1_wrapper)
{
  return pfunc1_wrapper();
}

int main(int argc, char ** argv)
{
  pfunc1_wrapper_t pfunc1_wrapper = NULL;
  int i = 0;

  pfunc1_wrapper = func1_abcd;
  i = func2(pfunc1_wrapper);

  pfunc1_wrapper = func1_xyz;
  i = func2(pfunc1_wrapper);

  ...

  return 0;
}

【讨论】:

    【解决方案3】:

    您应该首先使用函数指针来完成您想要的工作。使用 void 指针是一种方法,您可以事先知道将其转换为什么来解除引用。由于您传递的是函数的地址,因此无论如何都应该将其转换为函数指针。所以避免所有这些并声明 func 指针。如果您知道自己可以处理所有可能,请使用 void * 。例如。 memcpy 使用 void * 这是可以接受的,因为您只想将源位置的一堆数据复制到目标位置。

    #include <stdio.h>
    void func1(char * str)
    {
       printf("%s",str);
    }
    void func2(void * g)
    {
       void (*p) (char *);   //function pointer
       p = (void (*)(char *))g;//casting void * to pi.e func pointer reqiuired eitherways.
       p("Func pointer caller");
    }
    void main()
    {
       void * d = func1; // name of the function is itselt its address
       //printf("func1 = %d\nd = %d",func1,d);  
       func2(d);
    }
    

    这一切都可以通过一个简单的函数指针来避免。

    【讨论】:

    • 虽然它确实留下了一个问题(从 main 发送 *str)......这是我想要的功能。谢谢
    • @gauravmeena0708 是的,它没有提供此功能,因为没有直接的方法可以做到这一点。可能有解决方法,但它们只是针对这种特殊情况的解决方法,而不是一般的解决方法。
    • C 标准不允许将函数指针转换为数据指针,反之亦然。 stackoverflow.com/a/5579907/1005312
    • @Kludas 那么实现这一目标的替代方法是什么
    • @gauravmeena0708 看看我在下面提供的答案。
    【解决方案4】:

    参考此Function pointers 并阅读Wiki - Function Pointers,您将知道如何修复您的代码。

    【讨论】:

    • 按照 SO 的精神,一个好的答案至少包含对该问题的最小答案。然后参考可以帮助澄清细节或包含示例。
    【解决方案5】:

    Jatin 已经发布了函数指针的通用链接,很好地解释了函数指针。

    由于您希望传递的不是经典函数指针,而是一个函数指针,它的参数作为一个“函数指针”传递给另一个函数,我认为这不会起作用。

    但是为什么要传递一个带有参数的函数作为一个参数呢?这意味着,您使用参数传递的函数将仅返回一个结果,即在 func2 之外已知的结果(因为 func2 将调用 func1 并使用此已在外部定义的参数集)。那么为什么不直接将 func1 调用的结果传递给 func2 呢?

    【讨论】:

    • func2 是一个库函数,只能采用 void * 值。所以我可以传递函数或结构的地址......我只是想尝试这种方式。
    • 在这种情况下(因为您不能将 func1 的函数参数传递给 func2),我要么使用 func2 之外的参数调用 func1,然后只传递结果。如果无法以可传递的格式获得结果,则可以执行 func3,使用其参数调用 func1,并将指向 func3 的函数指针传递给 func2。这样你就有了一个指向没有参数的函数的函数指针。
    • 是的,我意识到,要么我传递两个变量,要么传递结构......就像@Kludas 在他的解决方案中所做的那样
    猜你喜欢
    • 2018-08-25
    • 1970-01-01
    • 2016-11-16
    • 1970-01-01
    • 1970-01-01
    • 2021-02-25
    • 2019-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多