[Linux] Аналог DLL

Garryss

Есть ли что-нибудь похожее?
Задача такая: нужно создать набор однотипных модулей (в каждой - по одной функции
которые должны будут обнаруживаться основной программой в момент её запуска.

rosali

so
PS. ае 1-ий

Garryss

.so
Хотя бы сказали, как их делать...
P.S. А я почему-то считал, что это статические библиотеки

Marinavo_0507

если по-простому, то
gcc -shared -fPIC -o plugin.so plugin.c
а по-другому я и не умею

rosali

man dlopen еще пригодится.

sergey_m

> man dlopen еще пригодится.
Наконец-то правильный ответ. Неужели кто-то думал, что человеку станет легче если он узнает, что вместо букв .dll буквы .so?

Marinavo_0507

Неужели кто-то думал, что человеку станет легче если он узнает, что вместо букв .dll буквы .so?
Да.

mira-bella

RTFM
google "dynamic linking"
man ld
man ld.so (man ld-linux.so)
man ldd
man ldconfig
man dlopen
man gcc

Garryss

man ld
man ld.so (man ld-linux.so)
man ldd
man ldconfig
man dlopen
man gcc
Не хочу тубя огорчать, но ссылки на эти статьи я уже видел в "man dlopen"

mira-bella

Не хочу тубя огорчать, но ссылки на эти статьи я уже видел в "man dlopen"
малаца, возьми с полки пирожок
для того там эти ссылки и написаны, чтобы ты их видел и читал соответствующие статьи, а не задавал мегабоянные, расписанные на каждом столбе, вопросы в форуме.
А что интересно меня в этом должно "огорчать"?

enochka1145

В сети (или в инете) можно скачать книжку Programming Linux Games. Там коротко и ясно рассказано про DLL под Linux. Рекомендую.

Garryss

Programming Linux Games
А вот за это спасибо, поищу.

Garryss

Взято где-то здесь
Будет на примере показано, как создавать библиотеки: статические, разделяемые и динамические.
Создание статической библиотеки
Файл libhello.h содержит прототип библиотечной функции
void hello(void);
Файл libhello.c содержит реализацию библиотечной функции
   
#include
void hello(void){
printf("Hello, library world.\n");
}

Файл demo_use.c содержит вызов библиотечной функции.
  
include "libhello.h"
int main{
hello;
return 0;
}

Теперь создадим статическую библиотеку и создадим исполняемый файл на основе libhello.h, libhello.c, demo_use.c . Ключ -g можно удалить, он используется только для проведения отладки при помощи gdb.
#Создаем объектный файл
gcc -Wall -g -c -o libhello-static.o libhello.c
#Создаем статическую библиотеку
ar rcs libhello-static.a libhello-static.o
#Если обладаете правами суперпользователя, то можно выполнить
#cp libhello-static.a /usr/local/lib/
#Иначе оставляем статическую библиотеку в текущей директории
#Создаем объектный файл
gcc -Wall -g -c demo_use.c -o demo_use.o
#Создаем исполняемый файл
#-L. - этот параметр указывает компилятору, что библиотеку следует искать в текущей директории.
#-lhello-static - этот параметр указывает компилятору, что библиотека помещается в файле
#libhello-static.расширение (.a, .o, .so).
gcc -g -o demo_use_static demo_use.o -L. -lhello-static
#Выполнение исполняемого файла
./demo_use_static
Для выполнения исполняемого файла demo_use_static уже не требуется существование файла libhello.a. Эта библиотека нужна была только при создании исполняемого файла.
Создание разделяемой библиотеки
Способ создания разделяемых библиотек зависит от ОС, однако обычно включает два этапа. Первый этап - создание объектного файла, содержащий код, не зависящий от места расположения (Position-Independent Code). Второй этап - создание собственно библиотеки.
#Создаем объектный файл, пригодный впоследствие для создания разделяемой библиотеки.
#Обращаем внимание на ключ -fPIC
gcc -fPIC -Wall -g -c libhello.c
#Создаем разделяемую библиотеку
#-lc - этот аргумент указывает, что компиляция происходи с участием стандартной C-библиотеки libc, поскольку libhello.o зависит от libc
#-Wl - предшествует параметрам, передаваемым линкеру (сборщику исполняемого файла)
gcc -g -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.0 libhello.c -lc
#Если обладаете правами суперпользователя, то можно выполнить
# cp libhello.so.0.0 /usr/local/lib/
#Ключ -n указывает ldconfig, что обработать нужно только директории указанные в командной строке, в данном случае - только текущую директорию.
/sbin/ldconfig -v -n .
#Создание символической ссылки
ln -sf libhello.so.0 libhello.so
#Создание объектного файла
gcc -Wall -g -c demo_use.c -o demo_use.o
#Создание исполняемого файла:
#-L. - этот параметр указывает компилятору, что поиск при компиляции необходимо проводить в текущей директории
#-lhello - этот параметр определяет имя файла, в котором содержится необходимая библиотека
gcc -g -o demo_use demo_use.o -L. -lhello
#Для выполнения необходимо, чтобы в переменной окружения LD_LIBRARY_PATH были перечислены через ":" директории, в которых следует искать библиотеки.
LD_LIBRARY_PATH="." ./demo_use
Для успешного выполнения необходимо, что файлы, содержащие библиотеки, присутствовали в указанных директориях. Если файлов нет в этих директориях, происходит поиск в стандарнтных директориях /lib и /usr/lib. По итогам создания этой статической библиотеки у вас возникнет файл libhello.so, являющийся символической ссылкой на файл libhello.so.0, который в свою очередь является символической ссылкой на файл libhello.so.0.0, который и содержит разделяемую библиотеку. Числа, идущие после "so." , называются версией и релизом библиотеки. Для того, чтобы определить с какими версиями библиотек скомпилирована программа, достаточно воспользоваться командой
ldd demo_use
При выполнении программы происходит поиск библиотеки с требуемым именем и версией, то есть поиск файл с именем lib<имя_библиотеки>.so.номер_версии. Этот файл является символической ссылкой на файл, содержащий собственно библиотеку. В имени этого файла уже будет присутствовать номер релиза. Такой механизм позволяет иметь несколько версий одной библиотеки.
Использование динамических библиотек
Необходимо сначала создать разделяемую библиотеку. Далее приводится текст программы, в которой происходит динамическое подгружение библиотеки.
   
/* demo_dynamic.c -- demonstrate dynamic loading and
use of the "hello" routine */
/* Need dlfcn.h for the routines to
dynamically load libraries */
#include
#include
#include
/* Note that we don't have to include "libhello.h".
However, we do need to specify something related;
we need to specify a type that will hold the value
we're going to get from dlsym. */
/* The type "simple_demo_function" describes a function that
takes no arguments, and returns no value: */
typedef void (*simple_demo_functionvoid);
int main(void) {
const char *error;
void *module;
simple_demo_function demo_function;
/* Load dynamically loaded library */
module = dlopen("libhello.so", RTLD_LAZY);
if (!module) {
fprintf(stderr, "Couldn't open libhello.so: %s\n",
exit(1);
}
/* Get symbol */
dlerror;
demo_function = dlsym(module, "hello");
if error = dlerror {
fprintf(stderr, "Couldn't find hello: %s\n", error);
exit(1);
}
/* Now call the function in the DL library */
(*demo_function;
/* All done, close things cleanly */
dlclose(module);
return 0;
}

Компиляция осуществляется следующими командами:
#создаем объектный файл
gcc -Wall -g -c demo_dynamic.c
#создаем исполняемый файл
#-ldl - этот параметр обеспечивает обращение к библиотеке libdl, которая обеспечивает
динамическое подгружение библиотек
gcc -g -o demo_dynamic demo_dynamic.o -ldl
Выполнение программы так же, как в случае разделяемых библиотек.
LD_LIBRARY_PATH="." ./demo_dynamic
Рекомендуется прочитать документацию для функцийй dlopen, dlclose, dlsym, dlerror, ar, ldd,nm.
Функции _init и _fini.
В библиотеке могут содержаться функции со специальными именами _init и _fini. Функция _init выполняется всегда непосредственно перед загрузкой библиотеки. Функция _fini выполняется всегда непосредственно перед выгрузкой библиотеки. Покажем на примере, как скомпилировать библиотеку, содержащую функцию _init. Файл libhello.c сделаем таким:
  
#include
void _init(void){
printf("Load library!\n");
}
void hello(void){
printf("Hello, library world?\n");
}

Объектный файл libhello.o создается без проблем. При попытке создать библиотеку получаем ошибку
gcc -g -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 libhello.o -lc
libhello.o: In function `_init':
/home/zubr/demo_library/shared/libhello.c multiple d

otets-mihail

ну ты бы еще man'ы сюда запостил

mira-bella


Это типа как пример "хорошего ответа" на твой первый пост?
Простыня из серии "программирование для начинающих". Да статья неплохая, но не думал же ты, что кто-то тебе напишет нечто подобное в этом треде.
Да, и такие статьи (учебного характера) есть в сети, и справочной информации тоже навалом. Теперь ты знаешь, как искать нужную тебе информацию (раз это нашел поздравляю.
Оставить комментарий
Имя или ник:
Комментарий: