我正在开发一个对主程序透明的C ++工具。即:如果用户只是将工具链接到他的程序,则该工具将被激活。为此,我需要调用两个函数,函数a()
,在main()
获得控制之前,在b()
完成后调用函数main()
。
我可以通过在程序中声明一个全局变量并通过返回代码a()
进行初始化来轻松完成。即
int v = a() ;
但在b()
完成后我找不到联系main()
的方法吗?
有人能想出办法吗?
该工具在Windows上运行,但我不想使用任何特定于操作系统的调用。
谢谢你,乔治
答案 0 :(得分:9)
使用RAII,在构造函数/析构函数中调用a和b。
class MyObj {
MyObj()
{
a();
};
~MyObj()
{
b();
};
};
然后只有一个MyObj的实例超出main()
的范围MyObj obj;
main()
{
...
}
有些事情需要注意。
答案 1 :(得分:4)
解决方案C:
看看atexit:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void bye(void)
{
printf("That was all, folks\n");
}
int main(void)
{
long a;
int i;
a = sysconf(_SC_ATEXIT_MAX);
printf("ATEXIT_MAX = %ld\n", a);
i = atexit(bye);
if (i != 0) {
fprintf(stderr, "cannot set exit function\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
http://linux.die.net/man/3/atexit
这仍然意味着你可以访问你的主,你可以添加atexit调用。如果您无法访问main,并且无法添加此函数调用,我认为没有任何选项。
修改强>
C ++中的解决方案:
as sudgested有一个来自std的c ++等价物。我只是在这里粘贴一个例子,我从代码下面的链接中复制了一个例子:
#include <iostream>
#include <cstdlib>
void atexit_handler_1()
{
std::cout << "at exit #1\n";
}
void atexit_handler_2()
{
std::cout << "at exit #2\n";
}
int main()
{
const int result_1 = std::atexit(atexit_handler_1);
const int result_2 = std::atexit(atexit_handler_2);
if ((result_1 != 0) or (result_2 != 0)) {
std::cerr << "Registration failed\n";
return EXIT_FAILURE;
}
std::cout << "returning from main\n";
return EXIT_SUCCESS;
}
答案 2 :(得分:1)
如果您愿意坚持使用单个编译器和非标准C / C ++,那么GCC的__attribute__((constructor))
和__attribute__((destructor))
可能会有用:
#include <stdio.h>
void __attribute__((constructor)) ctor()
{
printf("Before main()\n");
}
void __attribute__((destructor)) dtor()
{
printf("After main()\n");
}
int main()
{
printf("main()\n");
return 0;
}
结果:
Before main()
main()
After main()
答案 3 :(得分:1)
不是main
之前构建的任何全局变量,之后是否被破坏?我做了一个测试struct
,其构造函数在main
之前调用,然后在析构函数之后调用。
#include <iostream>
struct Test
{
Test() { std::cout << "Before main..." << std::endl; }
~Test() { std::cout << "After main..." << std::endl; }
};
Test test;
int main()
{
std::cout << "Returning now..." << std::endl;
return 0;
}
答案 4 :(得分:0)
除了析构函数之外,您可以以类似的方式使用atexit()
- 在C ++中,您无需访问main()
即可注册atexit
。您也可以在a()
中执行此操作 - 例如:
void b(void) {
std::cout << "Exiting.\n";
}
int a(void) {
std::cout << "Starting.\n";
atexit(b);
return 0;
}
// global in your module
int i = a();
话虽这么说,我也更喜欢全局C ++类对象,它会在析构函数中调用b()
内容。