views:

690

answers:

3

Hey, I was wondering if it's possible to use C constructors in VC just as it is possible to use them in GCC. The gcc way is quite straight using the attribute keyword, unfortunately VC doesn't seem to even know this keyword, as I'm not a Win32 programmer I wonder if there's some sort of equivalent keyword for such things. Just to note - this is a C program, not a C++ or C# even, (as 'twas quite easy to do that in those languages)

Anyone got a clue ?

Thanks in advance.

+1  A: 

You are probably interested in DllMain.

foxx1337
It must be executed _before_ entering main(), that's for dlls, how's that related ? :/
About the only real use people have for __attribute__((constructor)) is to use them in shared libraries similar to emulate a DllMain :)
nos
`__attribute__((constructor))` is useful even in a single program image; for example, inserting global hooks around library and system calls, or registering built-in "plugins", or initializing data structures that dynamically linked modules will need in their "`DllMain`"-alikes.
ephemient
+2  A: 

I don't think there's a way to avoid using C++ features with MSVC. (MSVC's C support sucks anyways.)

Untested, but this should at least allow the same code to work in both MSVC and GCC.

#if defined(_MSC_VER)
struct construct { construct(void (*f)(void)) { f(); } };
#define constructor(fn) \
    void fn(void); static constructor constructor_##fn(fn)
#elif defined(__GNUC__)
#define constructor(fn)
    void fn(void) __attribute__((constructor))
#endif

static constructor(foo);
void foo() {
    ...
}
ephemient
+1  A: 

Below C code demonstrates how to define a void(void) function to be called at program/library load time, before main executes.

For MSVC, places a ptr to the function in the user initializer section (.CRT$XCU), basically the same thing the compiler does for the constructor calls for static C++ objects. For GCC, uses a constructor attribute.



/* Initializer/finalizer sample for MSVC and GCC.
   2010 Joe Lowe. Released into the public domain.
   */

#include <stdio.h>

#ifdef _MSC_VER

#define CCALL __cdecl
#pragma section(".CRT$XCU",read)
#define INITIALIZER(f) \
   static void __cdecl f(void); \
   __declspec(allocate(".CRT$XCU")) void (__cdecl*f##_)(void) = f; \
   static void __cdecl f(void)

#elif defined(__GNUC__)

#define CCALL
#define INITIALIZER(f) \
   static void f(void) __attribute__((constructor));
   static void f(void)

#endif

static void CCALL finalize(void)
{
   printf("finalize\n");
}

INITIALIZER(initialize)
{
   printf("initialize\n");
   atexit(finalize);
}

int CCALL main(int argc,const char*const* argv)
{
   printf("main\n");
   return 0;
}

Joe
Hi Joe: great post! I really need the tricks for working with VC. It's critical to auto-register a unit test function in C(not C++).BTW: There should be a tailing \ in the second line of macro INITIALIZER
赵如飞