2012-12-31 13 views
7

EDYCJA: Wiem o załącznikach, ale dołącz do nich pliki o numerze , a nie. Mówię o rzeczywistym skompilowanym i już połączonym kodzie, który zostanie upieczony w bibliotece statycznej.Jak uniknąć tego samego kodu podczas korzystania z bibliotek C++?

Tworzę uniwersalną bibliotekę narzędzi dla siebie w C++.

Jedna z funkcji, które tworzę, printFile, wymaga string, cout i innych podobnych elementów standardowej biblioteki.

Obawiam się, że gdy biblioteka jest kompilowany, a następnie połączony z innym projektem, który również używa string i cout, kod string i cout zostanie powielona: będzie zarówno być prelinkowane binarne biblioteki program jest są powiązane i będą ponownie połączone z projektem, który sam je wykorzystuje.

Biblioteka jest skonstruowany tak:

  1. Istnieje jeden plik libname.hpp programista, który używa biblioteki ma #include w swoich projektach.
  2. Dla każdej funkcji fname zadeklarowanej w libname.hpp znajduje się plik fname.cpp implementujący ją.
  3. Wszystkie pliki fname.cpp również .
  4. Biblioteka sama się kompiluje w libname.a, która jest kopiowana do /usr/lib/.

Czy tak się stanie?
Jeśli tak, czy to w ogóle problem?
Jeśli tak, to w jaki sposób mogę tego uniknąć?

Odpowiedz

3

Obawiam się, że gdy biblioteka jest kompilowany, a następnie połączony z innym projektem, który również wykorzystuje ciąg i cout, kod ciągiem i cout zostanie powielona

nie martw się: nie zrobi tego żaden nowoczesny system kompilacji. Kod funkcji szablonu jest wysyłany do plików obiektowych, ale linker odrzuca zduplikowane wpisy.

0

Tak, kod standardowych elementów biblioteki zostanie zduplikowany. Może to stanowić problem, jeśli na przykład zwrócisz ciąg std :: string lub wziąłeś jeden jako parametr w jednej ze swoich metod. Może mieć inny układ w standardowej implementacji biblioteki niż w przypadku użytkownika.

+1

OK, rozumiem. Jednak "jak tego uniknąć" to duża część mojego pytania. – corazza

+0

Zdaję sobie teraz sprawę, że miksowałem dwa różne problemy: duplikację kodu i standardowe układy klas biblioteki. Druga kwestia nie stanowi problemu, jeśli kompilujesz swój program za pomocą tego samego kompilatora, którego użyłeś do kompilacji biblioteki, co wydaje się być twoim przypadkiem. Jeśli chodzi o pierwszy, może to skutkować większym kodem, ale w rzeczywistości nie stanowi problemu. – user1610015

3

Definicje bibliotek standardowej biblioteki C++ nie pojawią się w twojej własnej bibliotece statycznej, chyba że je w nich jawnie (tzn. Wyodrębnisz pliki obiektów ze standardowej biblioteki C++ i umieścisz je w swojej bibliotece). Biblioteki statyczne nie są w ogóle połączone i będą miały tylko niezdefiniowane odniesienia do innych bibliotek. Biblioteka statyczna to po prostu zbiór plików obiektowych definiujących symbole dostarczone przez bibliotekę. Definicje, które pochodzą z nagłówków, np. Funkcje wbudowane i instancje szablonów, zostaną zdefiniowane w taki sposób, że wiele definicji w wielu jednostkach tłumaczeniowych nie będzie w konflikcie. Tam, gdzie kod nie jest rzeczywiście wstawiony, definiuje symbole "słabe", które powodują ignorowanie lub usuwanie duplikatów w czasie połączenia.

Jedynym poważnym problemem jest to, że biblioteki połączone z plikiem wykonywalnym muszą korzystać z kompatybilnych definicji bibliotek. Z dużą ilością kodu znajdującego się w plikach nagłówkowych, stosunkowo częste są zmiany w plikach nagłówkowych C++, w tym w standardowych nagłówkach bibliotek C++ (w stosunku do nagłówków bibliotek C, które zawierają dużo mniej kodu).

0

To rzadko jest problem w praktyce.

Dla funkcji static wbudowanych i szablonowych zdefiniowanych w plikach nagłówkowych, nie ma się czym martwić: każda jednostka kompilacji otrzymuje własną kopię (np. W bibliotece .a może być już wiele anonimowych kopii). Jest to w porządku, ponieważ te definicje nie są eksportowane, więc linker nie musi się nimi martwić.

W przypadku funkcji zadeklarowanych przy użyciu niestatycznego połączenia problem związany z łączeniem biblioteki .a jest zależny od problemu.

Podczas kompilacji biblioteki zwykle łączysz się z , a nie w standardowej bibliotece C++. Utworzona biblioteka będzie zawierała niezdefiniowane odniesienia do standardowej biblioteki C++. Te muszą zostać rozwiązane przed zbudowaniem ostatecznego pliku wykonywalnego. Zwykle odbywa się to automatycznie po powiązaniu końcowego pliku binarnego w sposób domyślny (w zależności od kompilatora).

Są sytuacje, w których ludzie łączą w standardowej bibliotece C++ bibliotekę statyczną. Jeśli łączysz się z wieloma bibliotekami statycznymi, z których każda osadza inną bibliotekę (taką jak standardowa biblioteka C++), spróbuj spodziewać się kłopotów, jeśli są jakieś różnice w tych osadzonych bibliotekach. Na szczęście jest to rzadki problem, przynajmniej w przypadku toolchainu gcc. To jest narzędzie z narzędziami Microsoftu: more frequent problem.

W niektórych przypadkach rozwiązaniem jest utworzenie jednej lub więcej konfliktowych bibliotek statycznych w bibliotece dynamicznej. W ten sposób każda z tych dynamicznych bibliotek może statycznie połączyć swoją własną kopię problematycznej biblioteki. Dopóki biblioteka dynamiczna nie eksportuje symboli z problematycznej biblioteki i nie ma niezgodności w układzie pamięci, generalnie nie ma problemów.

Powiązane problemy