To jest kontynuacja kompilacji Dynamic Shared Library z g ++ .
Próbuję utworzyć współdzieloną bibliotekę klas w C ++ w systemie Linux. Jestem w stanie skompilować bibliotekę i mogę wywołać niektóre (nieklasowe) funkcje, korzystając z samouczków, które znalazłem tutaj i tutaj . Moje problemy zaczynają się, gdy próbuję użyć klas zdefiniowanych w bibliotece. Drugi samouczek, do którego dołączyłem, pokazuje, jak załadować symbole do tworzenia obiektów klas zdefiniowanych w bibliotece, ale zatrzymuje się na krótko przed użyciem tych obiektów do wykonania jakiejkolwiek pracy.
Czy ktoś zna bardziej kompletny samouczek dotyczący tworzenia współdzielonych bibliotek klas C ++, który pokazuje również, jak używać tych klas w oddzielnym pliku wykonywalnym? Bardzo prosty samouczek pokazujący tworzenie i używanie obiektów (proste metody pobierające i ustawiające byłyby w porządku) i usuwanie byłoby fantastyczne. Równie dobry byłby odsyłacz lub odniesienie do jakiegoś kodu open source, który ilustruje użycie współdzielonej biblioteki klas.
Chociaż odpowiedzi z codelogic i nimrodm działają, chciałem tylko dodać, że wybrałem kopię Beginning Linux Programming od czasu zadania tego pytania, a jej pierwszy rozdział zawiera przykładowy kod C i dobre wyjaśnienia dotyczące tworzenia i używania zarówno bibliotek statycznych, jak i współdzielonych . Te przykłady są dostępne za pośrednictwem Google Book Search w starszym wydaniu tej książki .
źródło
Odpowiedzi:
myclass.h
myclass.cc
class_user.cc
W systemie Mac OS X skompiluj z:
W systemie Linux skompiluj z:
Gdyby to było dla systemu wtyczek, użyłbyś MyClass jako klasy bazowej i zdefiniowałbyś wszystkie wymagane funkcje wirtualne. Autor wtyczki następnie wywodziłby się z MyClass, nadpisałby wirtualne i zaimplementował
create_object
idestroy_object
. Twoja główna aplikacja nie musiałaby być w żaden sposób zmieniana.źródło
extern "C"
ponieważdlsym
funkcja jest funkcją C. Aby dynamicznie załadowaćcreate_object
funkcję, użyje powiązania w stylu C. Gdybyś nie użył rozszerzeniaextern "C"
, nie byłoby możliwości poznania nazwycreate_object
funkcji w pliku .so z powodu zmiany nazw w kompilatorze C ++.Poniżej przedstawiono przykład współużytkowanej biblioteki klas. [H, cpp] i modułu main.cpp korzystającego z tej biblioteki. To bardzo prosty przykład, a plik makefile mógłby być znacznie lepszy. Ale to działa i może ci pomóc:
shared.h definiuje klasę:
shared.cpp definiuje funkcje getx / setx:
main.cpp używa klasy,
oraz plik makefile, który generuje libshared.so i łączy main z biblioteką współdzieloną:
Aby faktycznie uruchomić 'main' i połączyć się z libshared., prawdopodobnie będziesz musiał określić ścieżkę ładowania (lub umieścić ją w / usr / local / lib lub podobnym).
Poniższy kod określa bieżący katalog jako ścieżkę wyszukiwania bibliotek i uruchamia main (składnia bash):
Aby zobaczyć, że program jest powiązany z libshared. więc możesz spróbować ldd:
Wydruki na moim komputerze:
źródło
-L. -lshared -Wl,-rpath=$$(ORIGIN)
podczas łączenia i upuść toLD_LIBRARY_PATH=.
.Zasadniczo powinieneś dołączyć plik nagłówkowy klasy do kodu, w którym chcesz użyć klasy w bibliotece współdzielonej. Następnie podczas tworzenia linku użyj flagi „-l”, aby połączyć swój kod z udostępnioną biblioteką. Oczywiście wymaga to, aby plik .so był tam, gdzie system operacyjny może go znaleźć. Patrz 3.5. Instalowanie i używanie udostępnionej biblioteki
Korzystanie z dlsym jest przydatne, gdy w czasie kompilacji nie wiesz, której biblioteki chcesz użyć. To nie brzmi, jakby tak było w tym przypadku. Może zamieszanie polega na tym, że system Windows wywołuje dynamicznie ładowane biblioteki, niezależnie od tego, czy łączysz się w czasie kompilacji, czy w czasie wykonywania (za pomocą analogicznych metod)? Jeśli tak, możesz myśleć o dlsym jako odpowiedniku LoadLibrary.
Jeśli naprawdę potrzebujesz dynamicznie ładować biblioteki (tj. Są to wtyczki), to ten FAQ powinien pomóc.
źródło
Oprócz poprzednich odpowiedzi chciałbym zwrócić uwagę na fakt, że należy używać idiomu RAII (pozyskiwanie zasobów to inicjalizacja) aby być bezpiecznym w przypadku zniszczenia obsługi.
Oto kompletny przykład roboczy:
Deklaracja interfejsu
Interface.hpp
::Zawartość biblioteki współdzielonej:
Dynamiczna procedura obsługi bibliotek współdzielonych
Derived_factory.hpp
::Kod klienta:
Uwaga:
.hpp
i.cpp
pliki .new
/delete
przeciążenie.Dwa jasne artykuły, aby uzyskać więcej informacji:
źródło