George T.
George T.

Reputation: 119

How to invoke a C++ function after main() finishes

I am developing a C++ tool that should run transparent to main program. That is: if user simply links the tool to his program the tool will be activated. For that I need to invoke two functions, function a(), before main() gets control and function b() after main() finishes.

I can easily do the first by declaring a global variable in my program and have it initialize by return code of a(). i.e

int v = a() ;

but I cannot find a way to call b() after main() finishes?

Does any one can think of a way to do this?

The tool runs on windows, but I'd rather not use any OS specific calls.

Thank you, George

Upvotes: 4

Views: 2699

Answers (5)

EmDroid
EmDroid

Reputation: 6066

Alternatively to the destructor, you can use atexit() in a similar manner - in C++, you do not need to have access to main() to register atexit there. You can do that as well it in your a() - for example:

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();

That being said, I'd also prefer the global C++ class object, which will call the b() stuff in its destructor.

Upvotes: 0

Stefano
Stefano

Reputation: 4031

SOLUTION IN C:

have a look at 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

this still implies however that you have access to your main and you can add the atexit call. If you have no access to the main and you cannot add this function call I do not think there is any option.

EDIT:

SOLUTION IN C++:

as sudgested there is a c++ equivalent from std. I simply paste in here an example which i copied from the link available just below the code:

#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

Upvotes: 5

alteous
alteous

Reputation: 188

If you're happy to stick with a single compiler and non-standard C/C++, then GCC's __attribute__((constructor)) and __attribute__((destructor)) might be of use:

#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;
}

Result:

Before main()
main()
After main()

Upvotes: 1

Chiel
Chiel

Reputation: 6194

Isn't any global variable constructed before main and destructed afterward? I made a test struct whose constructor is called before main and the destructor afterward.

#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;
}

Upvotes: 1

Roddy
Roddy

Reputation: 68023

Use RAII, with a and b called in constructor/destructor.

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

Then just have an instance of MyObj outside the scope of main()

MyObj obj;

main()
{
  ...
}

Some things to note.

  • This is bog-standard C++ and will work on any platform
  • You can use this without changing ANY existing source code, simply by having your instance of MyObj in a separate compilation unit.
  • While it will run before and after main(), any other objects constructed outside main will also run at this time. And you have little control of the order of your object's construction/destruction, among those others.

Upvotes: 9

Related Questions