Код dlo.c (библиотека):
#include <stdio.h>
// function is defined in main program
void callb(void);
void test(void) {
printf("here, in lib\n");
callb();
}
Компилировать с
gcc -shared -olibdlo.so dlo.c
Здесь код основной программы (скопирован с man-страницы dlopen и настроен):
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
void callb(void) {
printf("here, i'm back\n");
}
int
main(int argc, char **argv)
{
void *handle;
void (*test)(void);
char *error;
handle = dlopen("libdlo.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
dlerror(); /* Clear any existing error */
*(void **) (&test) = dlsym(handle, "test");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}
(*test)();
dlclose(handle);
exit(EXIT_SUCCESS);
}
Сборка с
gcc -ldl -rdynamic main.c
Выход:
[js@HOST2 dlopen]$ LD_LIBRARY_PATH=. ./a.out
here, in lib
here, i'm back
[js@HOST2 dlopen]$
Опция -rdynamic
помещает все символы в таблицу динамических символов (которая отображается в памяти), а не только имена используемых символов. Подробнее об этом читайте здесь . Конечно, вы также можете предоставить указатели на функции (или структуру указателей на функции), которые определяют интерфейс между библиотекой и вашей основной программой. Это на самом деле метод, который я бы выбрал, вероятно. Я слышал от других людей, что это не так просто сделать -rdynamic
в Windows, и это также улучшит связь между библиотекой и основной программой (у вас есть точный контроль над тем, что можно вызывать, а что нет), но это также требует больше домашнего хозяйства.