Running Code Before and After Main

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

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

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read