【问题标题】:How do I pass a function with a fixed parameter to another method in C?如何将具有固定参数的函数传递给 C 中的另一个方法?
【发布时间】:2016-10-03 16:58:15
【问题描述】:

假设我有一个以 void* 作为参数的打印函数:

Print(void *instance)

如何将结构的成员设置为此方法?

struct Foo
{
    void(*Print)(); //this does not match to Print above!
    //void(*Print)(void* Instance); //This would but I cannot change this
}

那么我将如何改变这个方法:

void Init()
{
    struct Foo* k = malloc(sizeof(Foo));

    Foo->Print = &Print(k);   //does not work?!
    //Foo->Pring = &Print;     //would work if types were the same
}

我想在一个带有固定参数的结构内设置一个函数指针。

基本上,这是在 ANSI-C 中实现面向对象代码的一种方式。 源码工程是这样的:Object Orientation in C?!

这将是关于更改这段 C 代码:

String* r = New_String("Hello");
r->Free(r); //this works
r->Free();  //this is how it should be!

这样实例就不必自己传递给方法了。

总结:目标是在 Print 中获取 Foo 实例,例如 Foo->Print();

【问题讨论】:

  • 你打算怎么称呼它?您是否尝试使用指向带有参数的函数的指针,然后使用有效填充的参数调用它来为您分配函数指针时指定的任何内容?那是不可能的……你需要采取不同的方法。每个调用都必须显式传递参数。
  • 这正是问题所在。其他语言像这样支持它: Foo.Print = ()=>Print(k);也许可以以某种方式手动将 k 添加到每个调用的堆栈中?
  • 看来您已经发布了伪 C++ 代码并希望在 C 中做同样的事情。问题是代码看起来就像无效的 C 代码。建议将您的评论合并到帖子中并尝试更多地阐明您的目标,也许会添加示例调用。
  • 注意:C没有“方法”,它有功能。这些之间的本质区别似乎接近您问题的根源。您可以在 C 中使用一些面向对象编程的元素,但它看起来与 C++ 中的非常不同。我认为,你最好询问你想要完成的事情(足够具体),而不是询问这种特殊的、不可行的方法来完成它。
  • 我编辑了我的问题以澄清。我想实现类似 C++ 的语法。迄今为止最好的是 Foo->Print(Foo)。我想在 Print 中获取 Foo 而不将其作为参数显式传递。我如何做到这一点?

标签: c


【解决方案1】:

与:

Foo->Print = &Print(k);

您正在分配一个函数指针并且您正在“调用”带有参数的函数。那是错的。你可以做的是:

Foo->Print = Print;
Foo->Print = (void(*)())Print;    // if compiler complains, use a cast

因为Print是一个函数,编译器将它分配给结构体的函数指针字段时会使用它的地址。但是因为您的Print 函数与Print 字段不兼容,所以您必须使用强制转换来使编译器静音。您的 Print 函数被转换为“可以采用任意数量参数的函数”。只要您使用至少一个参数调用它,强制转换在这里是安全的。仅当您知道自己在做什么时才执行此转换,否则会出现未定义的行为。

分配函数指针后,您现在可以使用参数调用它:

Foo->Print(k);

【讨论】:

  • 坏事是 k 不应该在之后使用。我已经澄清了我的问题。疯狂的事情也是允许的。目标是以某种方式在 Print 中获取 Foo 引用。堆栈操作,汇编程序,一切顺利!
  • 加个成员k怎么样,比如Foo->k= k;等等Foo->Print(Foo->k);
  • 这就是它现在的工作方式。更好的是: Foo->Print(Foo) 因为您只需要地址。但我需要 Foo->Print();
  • 也许我不明白你的问题/评论,但你可以打电话给Foo->Print(Foo) 而你 Foo->Print(); 只有你不应该在没有至少一个的情况下打电话给它参数,因为您的 Print(void *instance) 需要一个参数。
猜你喜欢
  • 2016-12-21
  • 2020-01-13
  • 2013-03-19
  • 2012-12-24
  • 2014-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-19
相关资源
最近更新 更多