如何用atexit()注册一个非void函数?
How to register a non-void function with atexit()?
我正在尝试注册一个函数,该函数 return 是一个 int
,将在使用 atexit()
函数的程序结束时调用。 (具体来说,来自 ncurses 的 endwin()
函数。)
但是由于atexit()
需要一个指向void
函数的指针,我运行遇到了问题。我尝试了以下方法:
static_cast<void (*)()>(endwin)
但是 static_cast
从 int
函数到 void
函数似乎是不允许的。
我正在努力实现的目标是否可行?如果可行,如何实现?
注意:我愿意忽略函数的return值。
编辑:我还尝试创建一个 lambda 函数,它似乎可以满足我的要求:
atexit([]{ endwin(); });
与 wrapper/forwarding 函数相比,这是一个好的解决方案吗? (除此之外,它需要 C++11 并避免定义一个新函数,其唯一目的只是转发另一个函数。)
"Is what I'm trying to accomplish possible at all, and if yes, how?"
您只需为 endwin()
编写自己的包装函数并注册那个
void myEndwin() {
endwin();
}
无法转换函数指针。只需注册一个转发功能:
#ifdef __cplusplus
extern "C"
#endif
void endwin_wrapper() { endwin(); }
...
atexit(endwin_wrapper);
由于您将问题标记为 C++:如果您在 C++ 中定义转发函数,则需要将其声明为 extern "C"
以获得正确的语言链接。
根据当前的 C++ 标准,lambda 可能是解决此问题的最佳方法:
atexit([]{ endwin(); });
现在没有必要为了转发另一个函数而定义一个全新的命名函数。
如果有一天您决定需要在程序退出时调用更多函数,您可以通过对 atexit()
:
的新调用来定义它们
atexit(anotherCleanupFunction);
或者,您可以将它们添加到 lambda 主体中:
atexit([]{
anotherCleanupFunction();
endwin();
});
但是,当您有多个函数要在 atexit()
中注册时,一个单独的包装函数来保存所有这些函数可能是更好的解决方案。虽然没有唯一的正确答案,只需编写良好且清晰的代码即可。 (通过充满函数调用的 lambda 调用 atexit()
可能看起来相当混乱。)
我正在尝试注册一个函数,该函数 return 是一个 int
,将在使用 atexit()
函数的程序结束时调用。 (具体来说,来自 ncurses 的 endwin()
函数。)
但是由于atexit()
需要一个指向void
函数的指针,我运行遇到了问题。我尝试了以下方法:
static_cast<void (*)()>(endwin)
但是 static_cast
从 int
函数到 void
函数似乎是不允许的。
我正在努力实现的目标是否可行?如果可行,如何实现?
注意:我愿意忽略函数的return值。
编辑:我还尝试创建一个 lambda 函数,它似乎可以满足我的要求:
atexit([]{ endwin(); });
与 wrapper/forwarding 函数相比,这是一个好的解决方案吗? (除此之外,它需要 C++11 并避免定义一个新函数,其唯一目的只是转发另一个函数。)
"Is what I'm trying to accomplish possible at all, and if yes, how?"
您只需为 endwin()
编写自己的包装函数并注册那个
void myEndwin() {
endwin();
}
无法转换函数指针。只需注册一个转发功能:
#ifdef __cplusplus
extern "C"
#endif
void endwin_wrapper() { endwin(); }
...
atexit(endwin_wrapper);
由于您将问题标记为 C++:如果您在 C++ 中定义转发函数,则需要将其声明为 extern "C"
以获得正确的语言链接。
根据当前的 C++ 标准,lambda 可能是解决此问题的最佳方法:
atexit([]{ endwin(); });
现在没有必要为了转发另一个函数而定义一个全新的命名函数。
如果有一天您决定需要在程序退出时调用更多函数,您可以通过对 atexit()
:
atexit(anotherCleanupFunction);
或者,您可以将它们添加到 lambda 主体中:
atexit([]{
anotherCleanupFunction();
endwin();
});
但是,当您有多个函数要在 atexit()
中注册时,一个单独的包装函数来保存所有这些函数可能是更好的解决方案。虽然没有唯一的正确答案,只需编写良好且清晰的代码即可。 (通过充满函数调用的 lambda 调用 atexit()
可能看起来相当混乱。)