I want to have a global names
variable, which looks like that
char* names[NAMES_CAP];
int names_len = 0;
And I want every one who links to this library to be able to add an item to this list.
It's easy to do that from main
.
int main(int argc,char**argv) {
names[names_len++] = "new name";
names[names_len++] = "new name 2";
}
but what if I want to stack up two libraries? (ie, my library, libnames
holds the global variable. And if someone links to libnameuser
who uses libnames
, it will automatically add all names defined in libnameuser
to the names
array in libnames
.
Is there any way to do that?
In C++, I can insert the names[names_len++] = "..."
to the constructor of a global object, and it must be called. But can I do that with plain C?
If you are using gcc you can use the constructor attribute __attribute__((constructor))
to get the same effect. This is however non-standard C.
I would however recommend against this pattern since there is no control of ordering of any function run before main. I would rather find a nice method of hooking in all the "constructor" functions after main has started running.
Update: Refer to https://stackoverflow.com/a/2390626/270788 for updated version of this answer.
Below is a pre-processor abstration to support C static initializer functions with GCC and MSVC. The GCC version will also work with LLVM CC, maybe some other compilers as well.
The MSVC version works by placing a ptr to the static initializer function in a special section that is processed by the application or DLL startup code.
#if defined(__GNUC__)
#define INITIALIZER(f) \
static void f(void) __attribute__((constructor)); \
static void f(void)
#elif defined(_MSC_VER)
#define INITIALIZER(f) \
static void __cdecl f(void); \
__declspec(allocate(".CRT$XCU")) void (__cdecl*f##_)(void) = f; \
static void __cdecl f(void)
#endif
INITIALIZER(initializer_1) { names[names_len++] = "new name"; }
INITIALIZER(initializer_2) { names[names_len++] = "new name 2"; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With