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.