[LINUX] [C / C ++] [GCC] __attribute __ ((constructeur)) pour exécuter le traitement avant et après main

Résumé de la vérification et de l'utilisation de __attribute__ ((constructeur)) Notez que cela ne fonctionne pas partout en raison de l'extension de GCC.

Lors de l'inclusion dans la source

main.c


#include <stdio.h>

__attribute__((constructor))
static void constructor() {
	puts("constructor");
}

__attribute__((destructor))
static void destructor() {
	puts("destructor");
}

int main(int argc, char const* argv[])
{
	puts("call main");
	return 0;
}

Créer et exécuter des résultats


$ gcc main.c && ./a.out
constructor
call main
destructor

Lors de la liaison en tant que bibliothèque partagée

main.c


#include <stdio.h>

int main(int argc, char const* argv[])
{
	puts("call main");
	return 0;
}

sharedlib.c


#include <stdio.h>

__attribute__((constructor))
static void constructor() {
	puts("constructor");
}

__attribute__((destructor))
static void destructor() {
	puts("destructor");
}

Créer et exécuter des résultats


$ gcc -shared -fPIC sharedlib.c -o libconstructor.so
$ gcc main.c -L . -lconstructor
$ LD_LIBRARY_PATH=. ./a.out
constructor
call main
destructor

Lors de l'utilisation de LD_PRELOAD

En utilisant LD_PRELOAD, vous pouvez ajouter ultérieurement un traitement à n'importe quel programme.

main.c


#include <stdio.h>

int main(int argc, char const* argv[])
{
	puts("call main");
	return 0;
}

preload.c


#include <stdio.h>

__attribute__((constructor))
static void constructor() {
	puts("constructor");
}

__attribute__((destructor))
static void destructor() {
	puts("destructor");
}

Créer et exécuter des résultats


$ gcc main.c && ./a.out
call main

$ gcc -shared -fPIC preload.c -o preload.so
$ LD_PRELOAD=./preload.so ./a.out
constructor
call main
destructor

Quand il y a plusieurs __attribute__ ((constructeur))

Cela fonctionne bien même s'il y a plusieurs __attribute__ ((constructeur)). (Cependant, l'ordre d'exécution est inconnu, et il semble préférable d'éviter les traitements qui dépendent de l'ordre d'exécution)

main.c


#include <stdio.h>

__attribute__((constructor))
static void constructor1() {
	puts("constructor1");
}

__attribute__((destructor))
static void destructor1() {
	puts("destructor1");
}

int main(int argc, char const* argv[])
{
	puts("call main");
	return 0;
}

preload.c


#include <stdio.h>

__attribute__((constructor))
static void constructor2() {
	puts("constructor2");
}

__attribute__((destructor))
static void destructor2() {
	puts("destructor2");
}

Créer et exécuter des résultats


$ gcc main.c && ./a.out
constructor1
call main
destructor1

$ gcc -shared -fPIC preload.c -o preload.so
$ LD_PRELOAD=./preload.so ./a.out
constructor2
constructor1
call main
destructor1
destructor2

référence

Appeler une fonction avant main () -bk blog c++ - How exactly does attribute((constructor)) work? - Stack Overflow Essayez d'utiliser __attribute __ ((constructeur)): Book of Days de GCC gcc - C++ static initialization vs attribute((constructor)) - Stack Overflow

Recommended Posts

[C / C ++] [GCC] __attribute __ ((constructeur)) pour exécuter le traitement avant et après main
Traitement des insertions avant et après la fonction de vue avec le propre décorateur de vue de Pyramid