2009-08-17 17 views
6

Mam program, który implementuje system wtyczek przez dynamiczne ładowanie funkcji z niektórych plugin_name.so (jak zwykle).GCC/Linux: dodanie biblioteki statycznej do .so?

Ale z kolei mam statyczną bibliotekę "pomocnika" (pozwala wywołać ją helper.a), której funkcje są używane zarówno z głównego programu, jak i głównej funkcji wtyczki. Nie muszą w żaden sposób współdziałać, są tylko funkcjami pomocniczymi do manipulowania tekstem i takimi.

Ten program, po uruchomieniu, nie może zostać ponownie załadowany lub uruchomiony ponownie, dlatego oczekuję nowej funkcji "pomocnika" z wtyczki, a nie z głównego programu.

Więc moim zadaniem jest ... czy można wymusić ten "kod funkcji wtyczki" w .so, aby użyć (statycznie połączyć z?) Inną (prawdopodobnie nowszą) wersję "pomocnika" niż główny program?

Jak można to zrobić? być może przez statyczne łączenie lub w inny sposób dodawanie helper.a do plugin_name.so?

+0

Chciałbym dodać, że nie chcę lub nie chcę korzystać z nowej biblioteki pomocniczej z głównego programu. Chciałbym po prostu połączyć każdą nową wtyczkę z nowszą/lepszą biblioteką pomocniczą. – conejoroy

+0

Czy istnieje powód, dla którego nie można używać dynamicznego łączenia dla funkcji pomocnika? –

+0

Po uruchomieniu główny program nie może zatrzymać wykonywania, nawet w celu przeładowania nowszego helpera.so .. i program potrzebuje bardzo prostej funkcjonalności helpera, ponieważ jest tylko symbolem zastępczym dla wtyczek. więc wolę skompilować całą wtyczkę ponownie, jeśli mam nową/ulepszoną lub rozszerzoną bibliotekę pomocniczą. Myślę, że bardziej praktyczne jest rozpowszechnianie jednego .so (wtyczki) niż dwa .so (wtyczka i najbardziej aktualny pomocnik, z którego korzysta wtyczka). – conejoroy

Odpowiedz

6

Odpowiedź Nicka Meyera jest poprawna w systemach Windows i AIX, ale jest mało prawdopodobne, aby była poprawna na każdej innej platformie UNIX domyślnie.

Na większości platform UNIX ładowarka wykonawcze utrzymuje jednolitej przestrzeni nazwa wszystkich symboli, więc jeśli zdefiniować foo_helper w a.out, a także w plugin.so, a następnie zadzwonić foo_helper z zarówno pierwsza definicja widoczny na starcie program ładujący (zwykle od a.out) jest używany domyślnie dla połączeń zarówno.

Ponadto obraz jest skomplikowana przez fakt, że foo_helper nie mogą być wywożone ze a.out (a zatem mogą być niewidoczne dla ładowacza wykonawczego), chyba że używasz -rdynamic flagę lub kilka inne współdzielone referencje IT bibliotece. Innymi słowy, rzeczy mogą pojawiać do pracy jak Nick je opisał, to dodajesz wspólną bibliotekę do linii łączącej a.out i nie działają już w ten sposób.

Na platformach ELF (takich jak Linux) masz dużą kontrolę nad widocznością i wiązaniem symboli. Zobacz opis strony man -fvisibility=hidden i -rdynamic w GCC, a także -Bsymbolic w stronie man linkera.

Większość innych platform UNIX również ma możliwość kontrolowania powiązań symboli, ale jest to z konieczności zależne od platformy.

1

Jeśli program główny i biblioteka dynamiczna są statycznie połączone z helper.a, to nie powinieneś się martwić o mieszanie wersji helper.a (o ile nie robisz takich rzeczy jak wskaźniki pasujące przydzielone w helperie .a między granicami .exe i .so).

Kod wymagany w pliku helper.a jest wstawiany do faktycznego pliku binarnego, gdy jest on połączony z nim. Więc kiedy wywołasz helper.a z .exe, będziesz wykonywał kod z segmentu kodu twojego pliku wykonywalnego, a kiedy wywołasz helper.a z .so, będziesz wykonywał kod z części przestrzeń adresowa, w której plik .so został załadowany. Nawet jeśli wywołujesz tę samą funkcję w helper.a, wywołujesz dwa różne "wystąpienia" tej funkcji w zależności od tego, czy wywołanie zostało wykonane z pliku .exe, czy z .so.

+0

Rozumiem. ale w jaki sposób mogę dodać kod w libhelper.a do plugin.so w czasie kompilacji? powinienem określić coś jak "gcc -lhelper.a -static" podczas kompilowania plugin.so? – conejoroy

+0

Jeśli twoja biblioteka to libhelper.a, to podczas kompilowania plugin.a, przekaż -L * dir * -lhelper do gcc, gdzie * dir * jest ścieżką do libhelper.a. Nie trzeba określać -static, który jest używany podczas tworzenia biblioteki statycznej. –

+0

Ta odpowiedź jest poprawna tylko w ograniczonych warunkach, które nie zostały podane. –

Powiązane problemy