Inhaltsverzeichnis

Initialisierung und Deinitialisierung von dynamischen Libraries

Beim Laden/Entladen einer dynamischen Library besteht häufig Notwendigkeit, einige Funktionen automatisiert auszuführen. Beim Laden z.B. müssen globale Variablen initialisiert werden (davon abgesehen, dass globale Variablen in einer Library möglichst zu vermeiden sind). Beim Entladen z.B. müssen irgendwelche Aufräumarbeiten durchgeführt werden (z.B. Schließen von Logfiles).

:!: Diese Notwendigkein besteht insbesondere dann, wenn die dynamischen Library nicht zur Laufzeit des Programms geladen werden (dlopen() unter Linux bzw. LoadLibrary() unter Windows), sondern wenn sie gleich beim Starten des Programms durch den Betriebssystem-Loader gelinkt werden. In diesem Fall sind die Libraries bereits geladen, bevor die main()-Funktion die Kontrolle übernimmt. Die Initialisierungs-Funktion wird in diesem Fall ebenfalls vor und die Deinitialisierungs-Funktion nach der main()-Funktion aufgerufen (wenn die main() durch return() oder exit() bereits die Kontrolle abgegeben hat).

Es gibt verschiedene Mechanismen, dies zu realisieren.

Unix- / GCC-Variante

Man exportiert mittels __attribute__(()) Funktionen zum Initialisieren und Finalisieren der Library:

void __attribute__ ((constructor)) lib_initialize(void);
void __attribute__ ((destructor))  lib_finalize(void);
 
// Called when the library is loaded and before dlopen() returns.
void lib_initialize(void)
{
    // Lib-initialization code here.
}
 
// Called when the library is unloaded and before dlclose() returns.
void lib_finalize(void)
{
    // Clean-up code here.
}

In der veralteten Variante lauten diese Symbole _init() bzw. _fini() - die sind deprecated und sollen daher nicht mehr benutzt werden.

:!: Shared Libraries sollen nicht mit dem GCC Schalter -nostartfiles oder -nostdlib kompiliert/gelinkt werden! Durch diese Parameter werden die Constructor/Destructor-Routinen unterdrückt!

Links:

Solaris Compiler nutzen #pragma init and #pragma fini für diesen Zweck:

#pragma init(lib_initialize)
#pragma fini(lib_finalize)
 
void lib_initialize(void)
{
    // ...
}
 
void lib_finalize(void)
{
    // ...
}

Windows

// Return TRUE on success and FALSE if an error occurs. Returning FALSE will cause the library to be unloaded.
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
	switch (fdwReason)
	{
	case DLL_PROCESS_ATTACH:
		// Lib-initialization code here.
		break;
	case DLL_PROCESS_DETACH:
		// Clean-up code here.
		break;
	}
 
	return(TRUE);
}

Links:


Stand: 11.04.2016

EOF