2011-01-16 30 views
7

W mojej aplikacji mam 3 główne części:linkami: Statyczne vs Dynamiczny

  • Exe: Plik wykonywalny
  • Lib_A: biblioteka zawiera klasy Singleton i klasy bazowej dla niektórych obliczeń być stosowanie w Singleton klasa
  • Lib_B: biblioteka zawiera szereg klas pochodzących od podstawy w Lib_A

Dlatego, że mam klasy pochodne w Lib_B jest, chciałbym skompilować Lib_B w czasie wykonywania z Exe. Potrzebuję generować klasy pochodne podczas obliczeń bez kończenia całego systemu. To dla mnie zbyt ważne. Oznacza to, że początkowo mogę powiedzieć, że Lib_B1 jest ładowany dynamicznie, również mogę skompilować inne wersje Lib_B jako Lib_B2, Lib_B3, Lib_B4 itd. I ładować je również dynamicznie. Wszystkie biblioteki Lib_Bx będą miały funkcje punktu wejścia do eksportu klas w nich.

Więc biorąc pod uwagę następujące fakty:

  • Na starcie pojawi się różne liczby plików dzielących tę samą Lib_A.
  • Aplikacja musi działać w systemach Windows i Linux. Tak więc problemem jest częściowa platforma.
  • mam zamiar korzystać z niektórych bibliotek jak TBB, Boost, Qt, które mogą mieć swoje własne biblioteki jak tbb.dll itp

Jakie są plusy i minusy statycznie lub dynamicznie łączenie z Lib_A zarówno przed Exe i Lib_Bx's? Jak wpłynąć na wydajność, wielkość systemu itp.? Czy są jakieś niebezpieczne lub trudne sytuacje, które mogę zaszyfrować dla każdego systemu operacyjnego, muszę użyć tego samego kompilatora dla Exe, Lib_A i Lib_Bx.

Projekt całego systemu to dla mnie bardzo trudny problem, więc wszelkie uwagi zostaną docenione.

Dziękuję bardzo.

Odpowiedz

6

Z tego, co rozumiem w opisie projektu, należy dynamicznie łączyć Lib_A: jeśli statycznie łączysz Lib_A z każdą z bibliotek współdzielonych Lib_Bx, duplikujesz xx kod Lib_A i zmienne statyczne.

Say, jeśli masz klasę w Lib_A, które mają postać:

class BaseKlass 
{ 
    static int instance_count; 
    ... 
}; 

instance_count będzie powielony we wszystkich bibliotek dzielonych, co uniemożliwi BaseKlass liczyć jego wystąpień.

możliwość mogłaby być ugryziony przez bardziej subtelne problemy z wirtualnych stołach lub RTTI (dynamic_cast) itp

Trzeba spojrzeć na ten boost.python document który opisuje problemy związane z tym, co wymieniono.

Boost.python pozwala tworzyć moduły python (biblioteki dynamiczne), które mają być ładowane w tym samym procesie. Każdy moduł python utworzony za pomocą boost.python, jeśli mają one komunikować się razem na poziomie C++, na przykład wyprowadzenie klasy B w module z klasy A w innym module, powinien łączyć się dynamicznie z boost.python lib, aby uniknąć problemów.

3

Dużą zaletą łączenia statycznego jest to, że nie trzeba wysyłać pakietów DLL. O ile nie planujesz wysyłać nagiego pliku wykonywalnego, myślę, że to nie problem.

Dynamiczne łączenie ma kilka dużych zalet. Nie musisz przekompilowywać całej aplikacji za każdym razem, gdy wprowadzasz zmianę, tylko zmodyfikowane biblioteki DLL. Można rozpowszechniać zaktualizowane biblioteki DLL niezależnie od reszty aplikacji, o ile są one zgodne z ABI.

Może być łatwiej używać tego samego kompilatora w systemach Windows i Linux, ale zdecydowanie nie musisz używać tego samego kompilatora.

Dopóki trzymasz się przenośnych bibliotek, największą różnicą między systemami Windows i Linux jest zazwyczaj system kompilacji. Niektórzy deweloperzy utrzymują całkowicie oddzielne systemy kompilacji, ale istnieje wiele systemów do budowy wielu platform, takich jak cmake.

+0

No cóż, chcę użyć kompilatora MSVC++ w systemie Windows i kompilatorze Intel C++ w systemie Linux. Myślę, że oba generują lepiej zoptymalizowany kod niż GCC. Ta aplikacja służy tylko do mojego użytku. Nie chcę go sprzedawać. –

+0

@sad_man: Czy planujesz uzyskać prawa do redystrybucji VC i ICC? Powodzenia z tym. – ephemient

+0

@ephermient: Na razie nie rozprowadzam mojego wniosku. Ale jeśli sprzedam go w przyszłości, to oczywiście klient dostarczy swoją własną kopię kompilatora. Wiem, że to nie brzmi dobrze, ale to jest sztuczka, aby uzyskać szybkość skompilowanego kodu binarnego. Na razie jestem w porządku z VC i ICC. W najgorszym przypadku mogę rozpowszechniać aplikację z GCC w prawo? :) –

2

Chcesz utworzyć nowe środowisko wykonawcze klas? C++ nie działa tak. Klasy C++ są statyczne i powinny istnieć wszystkie czasy kompilacji. Współużytkowane, dynamicznie ładowane biblioteki nie mają na celu rozwiązania problemu.

Najprostszym rozwiązaniem może być osadzenie interpretera języka, który ma typy dynamiczne (np. Lua) i zapisanie w nim dynamicznych obiektów czasu wykonywania.

Jeśli naprawdę chcesz współdziałać z modułami kompilowanymi w czasie wykonywania w niezależny od platformy sposób, lepiej korzystaj z neutralnego językowo i neutralnego platformy interfejsu, takiego jak CORBA. Wtedy rzeczy skompilowane i uruchomione na twoim Linux-boxie i Windowsie będą mogły współdziałać ze sobą i skompilować nowych członków, aby dołączyć do gangu.

+0

Ale mogę nie skorzystać z szybkości i elastyczności C++. –

+0

Prędkość każdej aplikacji pochodzi przede wszystkim od wysokiej klasy programistów.Kod wygenerowany na podstawie czasu wprowadzania danych przez użytkownika nie powinien być wydajny, ale może być przydatny, gdy wydajność nie jest potrzebna, tak jak w przypadku prototypowania. Dlatego zaproponowałem użycie interpretera skryptów. –

+0

Tak Kod wygenerowany na podstawie czasu wejścia użytkownika nie powinien być skuteczny, ALE kod binarny skompilowany z czasu wejścia użytkownika powinien być znacznie szybszy niż kod z interpretera skryptu. –

0

W zasadzie jest to możliwe, jeśli wszystkie trzy są bibliotekami DLL - można wyzwolić kompilator z aplikacji, a następnie dynamicznie wczytać nową bibliotekę DLL. Jest to naprawdę tak jak każda inna architektura wtyczki (należy wziąć pod uwagę, że biblioteki DLL Lib_Bx są wtyczkami).

Chciałbym zapytać, czy jest to mądre podejście. Czy potrzebujesz pełnej elastyczności kompilatora C++ dla swojego rozwiązania? Czy profilowałeś różne sposoby rozwiązania problemu? Jeśli robisz przetwarzanie liczbowe, coś takiego jak OpenCL byłoby lepszym podejściem?

Powiązane problemy