LINUX.ORG.RU

[C] [линковка] про плагины

 ,


0

0

Доброго времени суток.

Хочу сделать так: в основной программе реализуется некоторая функция, которая затем используется в плагине. Но получаю ошибку линковки (уже в программе). Проблема назрела давно, но решалась реализацией этой функции в отдельной библиотеке, которая на этапе компоновки линковалась и к программе, и к плагину. Но не нравится мне такое решение.

Ниже следует минимальный пример:


$ cat file.h
void so_func();


$ cat file1.c
#include"file.h"
#include<stdio.h>

void so_func(){
printf("shared fucking object!\n");
}

#include<dlfcn.h>
int main(){
void *dl=dlopen("file.so",RTLD_NOW);
if(dl==0)printf("%s\n",dlerror());
return 0;
}


$ cat file2.c
#include"file.h"

void some(){
so_func();//!!!
}

$ gcc file2.c -o file.so -shared
$ gcc file1.c -o main -ldl -Wl,-rpath,.
$ ./main
./file.so: undefined symbol: so_func


Пробовал играться с разными флагами RTLD_, но либо никакого эффекта, либо вообще сегфолт (на вызове dlopen вероятно, не проверял).

★★★★★

Подозреваю, что нужно использовать указатель на функцию.

UVV ★★★★★
()
Ответ на: комментарий от JackYF

>Подозреваю, что нужно использовать указатель на функцию.

Не понял, к чему это.

>Посмотри libmodplug.

Если вы предлагаете посмотреть исходники, то нет, спасибо. Правильный ответ уже был дан в первом комментарии.

staseg ★★★★★
() автор топика
Ответ на: комментарий от alex_custov

Я считаю его неправильным. Потому что выносить в отдельную библиотеку код базовых классов плагинов неразумно. Имхо конечно, но базовые вещи реализуются в программе, а плагинами расширяются. Я не делаю мегакомбайн, работающий с любыми плагинами, у меня их несколько типов, а с помощью наследования в случае необходимости будут введены новые.

Да, проект на с++, но вопрос сворачивался до си.

staseg ★★★★★
() автор топика
Ответ на: комментарий от alex_custov

> правильный ответ - вынести общий код в отдельную библиотеку, и линковать с ней программу и плагины.

Это не всегда разумно. Например, в случае нахождения этого кода целиком в главной программе, мы можем гибко управлять видимостью с помощью '--dynamic-list' (к примеру), предоставляя плагинам доступ к чётко очерченным частям. При этом логически и с точки зрения кода предоставленные плагинам функции являются неотемлимой частью некоторого модуля/класса/etc, полный доступ к которому может быть (и должен) предоставлен только главной программе, например, из соображений безопасности.

kemm
()
Ответ на: комментарий от kemm

> Например, в случае нахождения этого кода целиком в главной программе, мы можем гибко управлять видимостью с помощью '--dynamic-list' (к примеру), предоставляя плагинам доступ к чётко очерченным частям.

но это не позволит управлять видимостью некоторой функции для _отдельных_ плагинов. в этом случае, как уже упоминалось выше, лучше экспортировать функции/переменные из главного модуля плагинам через указатели, т.е. после загрузки плагина передать ему указатель на приватную функцию/переменную, если данному плагину можно к ней обращаться.

arsi ★★★★★
()
Ответ на: комментарий от arsi

В этом случае -- да. Вообще, решение с указателями самое универсальное, но и самое трудоёмкое. С --export-dynamic куда как менее универсально, зато не требует никаких переделок. С вынесением в отдельную библиотеку -- по трудоёмкости сравнимо с указателями, по универсальности проигрывает обоим вариантам. 8))

kemm
()
Ответ на: комментарий от kemm

В моем случае вариант с отдельной библиотекой не трудоемкий (всего-то немного поправить Makefile), а велосипедный. И программа, и плагины используют базовый код плагинов из программы, а плагины - еще и свой дополнительный. Скрывать ничего не требуется.

Спасибо за ответы. И за дискуссию).

staseg ★★★★★
() автор топика
Ответ на: комментарий от kemm

> С --export-dynamic куда как менее универсально, зато не требует никаких переделок.

согласен, но, ИМХО, этот вариант больше подходит для проектов изначально не рассчитанных на модель ядро-плагины. или если это курсовая ;)

> С вынесением в отдельную библиотеку — по трудоёмкости сравнимо с указателями, по универсальности проигрывает обоим вариантам. 8))

почему же, если общая функция достаточно обособлена, то вынесение её в отдельную библиотеку потребует только незначительных правок Makefile.am, может даже сорцы трогать не придётся… хотя да, длл-хелл)

arsi ★★★★★
()
Ответ на: комментарий от arsi

> почему же, если общая функция достаточно обособлена...

Это если она там одна, ага. 8)) Для одной функции и указатель передать не проблема, в общем-то.

kemm
()
Ответ на: комментарий от staseg

базовые вещи на то и базовые, что они могут использоваться как _платформа_ для построения плагинов, и к программе-контейнеру как раз таки базовые классы не имеют строгого отношения. На C++ решение аналогичное - либо --export-dynamic либо общая библиотека. Это религиозный вопрос, о котором можно спорить вечно. Я предпочитаю общую библиотеку как более прозрачное, однозначное решение.

alex_custov ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.