Running Code Before and After Main

There are many reasons why sometimes you’d like to run some code before, or after, the main function of a program or DLL (main, WinMain, and DllMain are equivalent for this article, so I will generalize them as “the main function” from now on). This is not as simple in C as it is in C++. In C++, you can just declare a global or static instance of an object anywhere, and its constructor and destructor get called before and after the main function, respectively.

This article describes how to use a partially documented feature from the Microsoft C runtime library’s (CRT) initialization and termination code to make your code execute before and after the main function. Bet let’s start with a simple example to show how it works. In Visual Studio, create a project for an empty Windows program, add a “prepostdemo.c” file, and paste the following code into it. There’s no need to change settings, link extra libraries, or do anything special; this is an ordinary self-contained C program.

/* prepostdemo.c */
#include <windows.h>

int WINAPI WinMain(
   HINSTANCE hInstance,
   HINSTANCE hPrevInstance,
   PSTR szCmdLine,
   int iCmdShow)
{
   MessageBox(NULL, TEXT("Hello, Main Program!"), TEXT("Hello"), 0);

   return 0;
}

int PreMain1(void)
{
   MessageBox(NULL, TEXT("First Pre-Main Function"),
                    TEXT("PreMain1"), 0);
   return 0;
}

int PreMain2(void)
{
   MessageBox(NULL, TEXT("Second Pre-Main Function"),
                    TEXT("PreMain2"), 0);
   return 0;
}

int PostMain1(void)
{
   MessageBox(NULL, TEXT("First Post-Main Function"),
                    TEXT("PostMain1"), 0);
   return 0;
}

int PostMain2(void)
{
   MessageBox(NULL, TEXT("Second Post-Main function"),
                    TEXT("PostMain2"), 0);
   return 0;
}

typedef int cb(void);

#pragma data_seg(".CRT$XIU")
static cb *autostart[] = { PreMain1, PreMain2 };

#pragma data_seg(".CRT$XPU")
static cb *autoexit[] = { PostMain1, PostMain2 };

#pragma data_seg()    /* reset data-segment */

When you execute this program, you will see that PreMain1 and PreMain2 get called before WinMain, and PostMain1 and PostMain2 get called after WinMain (I used two pre- and post-functions here, but you can specify any number). On the next page, I will explain how it works.

More by Author

Must Read