【问题标题】:Send void type defined function pointer as argument to be called发送 void 类型定义的函数指针作为要调用的参数
【发布时间】:2012-07-02 06:15:33
【问题描述】:

我不知道我想要做的事情是否可行,但我很高兴。这将真正证明 C++ 是一门强大的语言。

所以,我有一个 DLL 和一个使用 DLL 导出的函数的 EXE。该函数接受一个参数,该参数是或必须是指向另一个函数的指针,并执行它。像这样的:

extern void RunFunction(void (*FunctionPonter)()) {
    (*FunctionPonter)();
}

我这样称呼它:

RunFunction(&FunctionToExecute);

作为参数发送的函数将没有参数,只是一个 void 函数。

所以,所有这些都有效,正如这里介绍的那样。现在,我想更进一步,将(*void)() 定义为,例如Action。

typedef (*void)() Action;

Action FunctionToExecute() {
    // My code. This function won't return results - void
}

我想将指针发送到我的 DLL 中的函数,如下所示:

// This is how it would be declared now in the DLL
extern void RunFunction(void (ACTION) {
    (*FunctionPonter)();
}

// and this is how I would like to use it
RunFunction(FunctionToExecute);

我正在使用 VC2010,如果可能的话,我不知道该怎么做。感谢您的想法、解释和帮助!

【问题讨论】:

  • 这开始很好,但后来变得完全不清楚。您希望您的第二个示例做什么,而您的第一个示例还没有做什么?
  • 只是为 void (*)() 创建一个 typedef,以区别于其他未创建为作为参数发送的 void 函数。就是这样!
  • C++确实是一门强大的语言,如果要求清晰合理!
  • typedef 不是一个新类型,它只是一个别名。所以void (*)() 和Action 对编译器来说是无法区分的。
  • 是的,但它们帮助我了解什么是作为参数发送给其他函数的函数 - 我将它们称为 Action 函数 - 以及其他函数可以调用的简单 void 函数跨度>

标签: c++ function pointers arguments


【解决方案1】:

首先,函数类型typedef的正确语法是

typedef void (*Action)();

其次,函数类型的 typedef-name 可用于声明该类型的函数,但不能用于定义此类函数。 IE。如果FunctionToExecute 是您要通过指针执行的函数,则必须将其定义为

void FunctionToExecute() {
  /* whatever */
}

调用函数将被定义为

void RunFunction(ACTION p) {
  p();
}

对它的调用如下所示

RunFunction(FunctionToExecute);

就是这样。一元 * 和 & 运算符对于函数指针是可选的。

【讨论】:

  • 谢谢。那是我的错误,将要发送的函数定义为函数 typedef。谢谢大家!
  • "函数类型的 typedef-name 可用于声明函数,但不能在函数定义中使用。" - 这太严格了,正如你自己的void RunFunction(Action p) { } 所示。这在定义中使用 typedef-name Action。 typedef 可用于参数或返回类型,但 typedef 不能用作定义中函数的完整类型。根本原因是Action FunctionToExecute() 定义了一个返回 Action 的函数,而不是一个是 Action 的函数。
  • @MSalters:是的,这只是我的措辞不好。同时,我不同意您的“根本原因”。我想说,通过 typedef-name 进行函数定义的潜在(发明)语法看起来像 Action FunctioToExecute { /* body */ },即名称后面没有 ()(与当前合法的声明语法 Action FunctioToExecute; 一致)。在我看来,真正的根本原因是无法提供参数名称。
【解决方案2】:

好的,如果我正确理解您的问题,您正在寻找一种方法,只允许将某些函数作为参数传递给您的 DLL 函数。

使用 typedef 是行不通的,因为它只会创建一个别名; Action 和 void (*)() 在您的代码中与编译器无法区分。相反,您必须创建一个全新的类型。在 C++ 中,您应该强烈考虑使用functor:

// Abstract functor
struct Action {
    virtual void operator() () const = 0;
};

// The DLL function
void RunFunction(const Action &action) {
    action();
}

// Define your function as a derived functor
struct FunctionToExecute : Action {
    void operator() () const { std::cout << "Hello\n"; }
};

// Run a function
RunFunction(FunctionToExecute());

演示:http://ideone.com/5pl23.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-03
    • 2020-06-11
    • 2016-12-13
    • 2016-11-23
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多