2012-10-09 14 views
5

Czytam książkę O'Reilly 21st Century C, w której autor stwierdza, że ​​podczas łączenia z biblioteką statyczną "kompilator [skutecznie] kopiuje odpowiednią zawartość biblioteki do ostatecznego pliku wykonywalnego".W jaki sposób kod obiektowy jest kopiowany do pliku wykonywalnego podczas łączenia z biblioteką statyczną?

Próbowałem to sprawdzić, tworząc własną bibliotekę statyczną składający się z tym module:

static char szStr[64]; 

char* single_func() { 
    strcpy(szStr, "Hello string!\r\n"); 
    return szStr; 
} 

void func0() { 
    strcpy(szStr, "Hello"); 
} 

char* func1() { 
    strcat(szStr, " string!\r\n"); 
    return szStr; 
} 

do testowania stworzony do plików C, gdzie jeden dzwoni single_func() i func0 innych połączeń() i func1().

Wynikowe pliki wykonywalne to 751290B w obu przypadkach. Jeśli wywołasz strcpy i strcat bezpośrednio z modułów, oba pliki stają się 7215B.

Czy nie jest to sprzeczne z powyższym stwierdzeniem, czy też brakuje mi szczegółów dotyczących łączenia?

Powiązanym pytaniem jest to, że biblioteka statyczna ma 1600B, więc skąd wziął się ten wzrost?


dodatkowe:

Oba główne formaty składają się z niczym więcej niż wywołanie funkcji i drukowanie wyników, tak:

main0:

#include <stdio.h> 
#include "sharedlib.h" 
int main() { 
    char* szStr = single_func(); 
    printf("%s", szStr); 
    return 0; 
} 

Main1:

#include <stdio.h> 
#include "sharedlib.h" 
int main() { 
    char* szStr; 
    func0(); 
    szStr = func1(); 
    printf("%s", szStr); 
    return 0; 
} 

Pliki zostały opracowane tak:

gcc -static main0.c -L. -lsharedlib -o main0 

Platforma jest linux i kompilator gcc v4.6.3 jest.

Odpowiedz

3

W przypadku bibliotek statycznych jednostką kopiowania jest plik obiektowy w bibliotece. Ponieważ oba programy wywołują funkcję z pliku obiektowego, oba programy kończą się wszystkimi plikami obiektów w pliku wykonywalnym, stąd ten sam wynik rozmiaru (podaj lub pobierz rozmiar wywołującego programu main()).

Dodatkowe informacje w pliku wykonywalnym mogą pochodzić z wielu miejsc. Niektóre z nich będą kontrolować i debugować informacje. Niektóre z nich mogą pochodzić z biblioteki C, jeśli połączono ją statycznie. Najprawdopodobniej będziemy musieli zobaczyć główny program i linie link, i znać platformę, aby wymyślić inne przyczyny inflacji.

+1

Mam zaktualizowane moje pytanie z dodatkowymi informacjami, o które prosiłeś, ale myślę, że mogę zacząć widzieć, gdzie to się dzieje. 1: Podczas korzystania z pojedynczej funkcji z pliku obiektu biblioteki cały plik obiektowy jest zwijany do pliku wykonywalnego. 2: przy użyciu opcji -static biblioteki _all_ są wyrzucane do końcowego pliku wykonywalnego, tworząc większy rozmiar pliku. Czy mam rację? – Kenneth

+1

Tak; masz rację w obu szczegółach. Jeśli spojrzysz na książkę "Standardowa biblioteka C" (dla standardu C89), zobaczysz, że większość plików źródłowych ma jedną zewnętrznie widoczną funkcję, więc nie przeciągasz tego, czego nie używasz do pliku wykonywalnego. Prawdopodobnie można znacznie zmniejszyć rozmiar pliku wykonywalnego, dodając '-shared' do wiersza poleceń po' -lsharedlib'. –

+0

Jestem trochę zaskoczony, że biblioteka C jest (wydaje się być) połączona statycznie. Pewnego razu (prawdopodobnie dziesięć lat temu) pomyślałem, że biblioteka C nie została dostarczona jako biblioteka statyczna (więc musiała być udostępniona).Być może błędnie oceniam, lub może to być wariant uniksowy, a nie Linux. Możesz sprawdzić, co jest ładowane jako biblioteka współdzielona z 'ldd main0'. Wyświetli listę udostępnionych obiektów. –

Powiązane problemy