Добавление модулей расширения (плагинов)
к программе.
Автор: Tom Bradley
Перевод: Андрей Киселев
#include <unistd.h> #include <string.h> #include <errno.h> #include <dlfcn.h> #define PATH_LENGTH 256 int main(int argc, char * argv[]) { char path[PATH_LENGTH], * msg = NULL; int (*my_entry)(); void * module; /* сборка имени модуля и полного пути к нему в одну строку */ getcwd(path, PATH_LENGTH); strcat(path, "/"); strcat(path, argv[1]); /* загрузка модуля и разрешение имен перед возвратом из dlopen */ module = dlopen(path, RTLD_NOW); if(!module) { msg = dlerror(); if(msg != NULL) { dlclose(module); exit(1); } } /* попытка получить адрес функции "entry" */ my_entry = dlsym(module, "entry"); msg = dlerror(); if(msg != NULL) { perror(msg); dlclose(module); exit(1); } /* вызов функции "entry" в модуле */ my_entry(); /* close module */ if(dlclose(module)) { perror("error"); exit(1); } return 0; } |
$ gcc -o loader main.c -ldl |
int entry() { printf("Я - первый модуль!\n"); return 0; } |
int entry() { printf("Я - второй модуль!\n"); return 0; } |
$ gcc -fPIC -c module1.c $ gcc -shared -o module1.so module1.o $ gcc -fPIC -c module2.c $ gcc -shared -o module2.so module2.o |
$ ./loader module1.so Я - первый модуль! $ ./loader module2.so Я - второй модуль! |
__attribute__ ((constructor)) void init() { /* этот код вызывается сразу после загрузки модуля функцией dlopen() */ } __attribute__ ((destructor)) void fini() { /* этот код вызывает непосредственно перед выгрузкой модуля функцией dlclose() */ } |
Copyright (C) 2002, Tom Bradley.