如何在main()完成后调用C ++函数

时间:2016-04-14 08:32:51

标签: c++ function

我正在开发一个对主程序透明的C ++工具。即:如果用户只是将工具链接到他的程序,则该工具将被激活。为此,我需要调用两个函数,函数a(),在main()获得控制之前,在b()完成后调用函数main()

我可以通过在程序中声明一个全局变量并通过返回代码a()进行初始化来轻松完成。即

int v = a() ;

但在b()完成后我找不到联系main()的方法吗?

有人能想出办法吗?

该工具在Windows上运行,但我不想使用任何特定于操作系统的调用。

谢谢你,乔治

5 个答案:

答案 0 :(得分:9)

使用RAII,在构造函数/析构函数中调用a和b。

class MyObj {
MyObj()
  {
   a();
  };
~MyObj()
  {
    b();
  };
};

然后只有一个MyObj的实例超出main()

的范围
MyObj obj;

main()
{
  ...
}

有些事情需要注意。

  • 这是沼泽标准的C ++,适用于任何平台
  • 您可以在不更改任何现有源代码的情况下使用它,只需将MyObj实例放在单独的编译单元中即可。
  • 虽然它将在main()之前和之后运行,但是在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;
}

http://en.cppreference.com/w/cpp/utility/program/atexit

答案 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()内容。