Co to jest biblioteka uruchomieniowa języka C?

157

Czym właściwie jest biblioteka wykonawcza języka C i do czego jest używana? Szukałem, szukałem w Google jak diabeł, ale nie mogłem znaleźć nic lepszego niż Microsoft: „Biblioteka wykonawcza firmy Microsoft zapewnia procedury programowania dla systemu operacyjnego Microsoft Windows. Procedury te automatyzują wiele typowych zadań programistycznych, których nie zapewnia języki C i C ++. ”

OK, rozumiem, ale na przykład, co jest w libcmt.libśrodku? Co to robi? Myślałem, że standardowa biblioteka C jest częścią kompilatora C. Czy więc libcmt.libimplementacja funkcji biblioteki standardowej C w systemie Windows działa pod win32?

B.Gen.Jack.O. Neill
źródło

Odpowiedzi:

71

Tak, libcmt jest (jedną z kilku) implementacją standardowej biblioteki C dostarczonej z kompilatorem Microsoftu. Udostępniają wersje „debugowania” i „wydania” trzech podstawowych typów bibliotek: jednowątkowych (zawsze połączonych statycznie), wielowątkowych połączonych statycznie i wielowątkowych połączonych dynamicznie (chociaż w zależności od wersji kompilatora, przy użyciu, niektóre z nich mogą nie być obecne).

Tak więc w nazwie „libcmt” „libc” jest (mniej lub bardziej) tradycyjną nazwą biblioteki C. „Mt” oznacza „wielowątkowy”. Wersja "debugująca" miałaby na końcu "d", co daje "libcmtd".

Jeśli chodzi o funkcje, które zawiera, standard C (część 7, jeśli Ci zależy) definiuje zestaw funkcji, które musi dostarczyć zgodna (hostowana) implementacja. Większość dostawców (w tym Microsoft) samodzielnie dodaje różne inne funkcje (ze względu na kompatybilność, w celu zapewnienia możliwości, których standardowe funkcje nie uwzględniają itp.) W większości przypadków będzie zawierał również kilka funkcji „wewnętrznych” używanych przez kompilator ale zwykle nie przez użytkownika końcowego.

Jeśli chcesz uzyskać pełną listę funkcji w „libcmt” (na przykład), możesz otworzyć jeden z monitów poleceń programu Visual Studio (zwykle w sekcji „Narzędzia programu Visual Studio”), przełącz się do katalogu, w którym znajdowały się Twoje biblioteki zainstalowane i wpisz coś w rodzaju: lib -list libcmt.liba wygeneruje ( długą ) listę nazw wszystkich plików obiektowych w tej bibliotece. Nie zawsze odpowiadają one bezpośrednio nazwom funkcji, ale generalnie dają pomysł. Jeśli chcesz przejrzeć określony plik obiektowy, możesz użyć lib -extractdo wyodrębnienia jednego z tych plików obiektowych, a następnie użyć, dumpbin /symbols <object file name>aby znaleźć funkcje, które są w tym konkretnym pliku obiektowym.

Jerry Coffin
źródło
37
Nie powiedziałeś, czym jest "biblioteka uruchomieniowa C" !!
onmyway133
4
@entropy: Jasne, wydaje mi się, że tak jak ja, ale krótka odpowiedź jest taka, że ​​jest to zbiór funkcji, z których wiele (ale niekoniecznie wszystkie) jest określonych w części 7 standardu C.
Jerry Coffin
3
Ta odpowiedź sugeruje, że biblioteki C są tylko częścią łańcucha narzędzi kompilatora. Niedokładne.
jiggunjer
@JerryCoffin Pytanie: czy więc strcpyfunkcja ze standardowej biblioteki C, na przykład, miałaby swoją implementację w bibliotece wykonawczej, czy po prostu miałaby swój kod w zwykłych plikach .c?
forumulator
@forumulator: zwykle w pliku .c będzie kod źródłowy, który jest kompilowany w celu utworzenia właściwej biblioteki standardowej (..dll, lib, .a, .so lub cokolwiek innego, co ma zastosowanie do używanego systemu) .
Jerry Coffin
56

Na początku powinniśmy zrozumieć, czym jest biblioteka uruchomieniowa; i zastanów się, co to może oznaczać przez „Microsoft C Runtime Library”.

patrz: http://en.wikipedia.org/wiki/Runtime_library

Opublikowałem tutaj większość artykułu, ponieważ może on zostać zaktualizowany.

Gdy kod źródłowy programu komputerowego jest tłumaczony na odpowiedni język docelowy przez kompilator, spowodowałoby to ekstremalne powiększenie kodu programu, gdyby każde polecenie w programie i każde wywołanie funkcji wbudowanej powodowałoby generowanie w miejscu całego odpowiedniego kodu programu w języku docelowym za każdym razem. Zamiast tego kompilator często używa specyficznych dla kompilatora funkcji pomocniczych w bibliotece wykonawczej, które są w większości niedostępne dla programistów aplikacji. W zależności od producenta kompilatora, biblioteka uruchomieniowa czasami zawiera również standardową bibliotekę odpowiedniego kompilatora lub jest w niej zawarta.

Również niektóre funkcje, które mogą być wykonywane tylko (lub są bardziej wydajne lub dokładne) w czasie wykonywania, są zaimplementowane w bibliotece wykonawczej, np. Niektóre błędy logiczne, sprawdzanie granic tablicy, dynamiczne sprawdzanie typów, obsługa wyjątków i ewentualnie funkcja debugowania. Z tego powodu niektóre błędy programistyczne nie są wykrywane, dopóki program nie zostanie przetestowany w „żywym” środowisku z rzeczywistymi danymi, pomimo wyrafinowanego sprawdzania w czasie kompilacji i testów przed wydaniem. W takim przypadku użytkownik końcowy może napotkać komunikat o błędzie w czasie wykonywania.

Zwykle biblioteka wykonawcza realizuje wiele funkcji, uzyskując dostęp do systemu operacyjnego. Wiele języków programowania ma wbudowane funkcje, które niekoniecznie muszą być realizowane w kompilatorze, ale można je zaimplementować w bibliotece wykonawczej. Tak więc granica między biblioteką wykonawczą a biblioteką standardową zależy od producenta kompilatora. Dlatego biblioteka środowiska uruchomieniowego jest zawsze specyficzna dla kompilatora i platformy.

Pojęcie biblioteki wykonawczej nie powinno być mylone ze zwykłą biblioteką programów, taką jak ta utworzona przez programistę aplikacji lub dostarczona przez osobę trzecią lub bibliotekę dynamiczną, co oznacza bibliotekę programów połączoną w czasie wykonywania. Na przykład język programowania C wymaga tylko minimalnej biblioteki wykonawczej (powszechnie nazywanej crt0), ale definiuje dużą bibliotekę standardową (zwaną biblioteką standardową C), którą musi dostarczyć każda implementacja.

fantagony
źródło
3
Podświetlone zdanie jako sposób na odróżnienie od standardowej biblioteki jest pierwszą zwięzłą, dokładną odpowiedzią, której nie widziałem jako „większość” lub „czasami”.
nik.shornikov
@ nik.shornikov: To dlatego, że inne opisy starają się być dokładniejsze. Chociaż prawdą jest, że standardowa biblioteka jest zwykle specyficzna dla kompilatora i platformy, nie zawsze jest to prawdą. Na przykład przynajmniej niektóre wersje zarówno Mingw, jak i kompilatora C ++ firmy Intel dla systemu Windows wykorzystywały standardową bibliotekę Microsoftu, zamiast dostarczać własne. Podobnie Clang w systemie Linux można (i często jest) instalowany w celu korzystania z biblioteki standardowej w istniejącej instalacji gcc, zamiast instalować inną dla siebie.
Jerry Coffin
Jestem dość pewny, że możliwe jest napisanie implementacji bibliotek standardowych C i C ++, które są przenośne na dowolną platformę obsługującą POSIX.
Jerry Coffin
20

Właśnie o to zapytałem i przez kilka godzin raniłem mózg. Nadal nie znalazłem niczego, co naprawdę ma rację. Każdy, kto coś pisze na jakiś temat, nie jest w stanie tak naprawdę „uczyć”. Jeśli chcesz kogoś uczyć, weź najbardziej podstawowy język, który dana osoba rozumie, aby nie musiał przejmować się innymi tematami podczas prowadzenia tematu. Więc doszedłem do wniosku, który wydaje się dobrze pasować do całego tego chaosu.

W języku programowania C każdy program zaczyna się od funkcji main (). Inne języki mogą definiować inne funkcje, w których program jest uruchamiany. Ale procesor nie zna main (). Procesor zna tylko predefiniowane polecenia, reprezentowane przez kombinacje „0” i „1”.

W programowaniu mikroprocesorowym, który nie ma podstawowego systemu operacyjnego (Microsoft Windows, Linux, MacOS, ...), musisz wyraźnie powiedzieć procesorowi, od czego zacząć, ustawiając ProgrammCounter (PC), który iteruje i skacze (pętle, wywołania funkcji) w polecenia znane procesorowi. Musisz wiedzieć, jak duża jest pamięć RAM, musisz ustawić pozycję stosu programu (zmienne lokalne), a także pozycję sterty (zmienne dynamiczne) i lokalizację zmiennych globalnych (chyba nazywało się to SSA ?) w pamięci RAM. Pojedynczy procesor może wykonywać tylko jeden program na raz.

W tym miejscu pojawia się system operacyjny. Sam system operacyjny jest programem działającym na procesorze. Program umożliwiający wykonanie kodu niestandardowego. Uruchamia wiele programów jednocześnie, przełączając się między kodami wykonywania programów (które są ładowane do pamięci RAM). Ale system operacyjny JEST PROGRAMEM, każdy program jest napisany inaczej. Samo umieszczenie kodu programu niestandardowego w pamięci RAM go nie uruchomi, system operacyjny o tym nie wie. Musisz wywołać funkcje w systemie operacyjnym, który rejestruje twój program, powiedzieć systemowi operacyjnemu, ile pamięci potrzebuje program, gdzie znajduje się punkt wejścia do programu (funkcja main () w przypadku C). Wydaje mi się, że to właśnie znajduje się w RuntimeLibrary i wyjaśnia, dlaczego potrzebujesz specjalnej biblioteki dla każdego systemu operacyjnego,

To wyjaśnia również, dlaczego NIE jest on dynamicznie łączony w czasie wykonywania, tak jak pliki .dll, nawet jeśli nosi nazwę RUNTIMELibrary. Biblioteka RuntimeLibrary musi być połączona statycznie, ponieważ jest potrzebna podczas uruchamiania programu. RuntimeLibrary wstrzykuje / łączy Twój program niestandardowy do / z innym programem (systemem operacyjnym) w RUNTIME. To naprawdę powoduje, że mózg ...

Wniosek: RUNTIMELibrary nie powiodła się w nazewnictwie. Być może we wczesnych czasach nie było .dll (linkowanie w czasie wykonywania), a problem zrozumienia różnicy po prostu nie istniał. Ale nawet jeśli to prawda, nazwa jest źle wybrana.

Lepszymi nazwami dla RuntimeLibrary mogłyby być: StartupLibrary / OSEntryLibrary / SystemConnectLibrary / OSConnectLibrary

Mam nadzieję, że dobrze zrozumiałem, czekam na poprawki / okrzyki rozszerzeń.

Huk
źródło
1
Nadal nie rozumiem idei. Dlaczego program potrzebuje czegoś w środowisku wykonawczym? Dlaczego kod binarny nie może działać w 100% sam, bez żadnego wsparcia w czasie wykonywania? Innymi słowy: czy jest możliwe, aby kod działał w 100% bez niczego (łącznie z systemem operacyjnym)?
MarcioAB
5
Teoretycznie program nie potrzebuje RTL. Jednak w jaki sposób twój program mógłby kiedykolwiek wyświetlić swój wynik, pobierać dane wejściowe lub żądać pamięci bez współpracy z systemem operacyjnym?
SN
16

C jest językiem i zgodnie z jego definicją nie muszą być dostępne żadne funkcje. Bez IO, bez procedur matematycznych i tak dalej. Zgodnie z konwencją, istnieje zestaw procedur, które możesz połączyć ze swoim plikiem wykonywalnym, ale nie musisz ich używać. Jest to jednak tak powszechna czynność, że większość konsolidatorów nie prosi już o linkowanie do bibliotek C runtime.

Są chwile, kiedy ich nie chcesz - na przykład podczas pracy z systemami wbudowanymi posiadanie malloc może być niepraktyczne. Kiedyś pracowałem nad osadzaniem PostScript w drukarkach i mieliśmy własny zestaw bibliotek wykonawczych, które były dużo szczęśliwsze w systemach wbudowanych, więc nie zawracaliśmy sobie głowy „standardem”.

cokół
źródło
11
W rzeczywistości standardy C opisują dwa typy środowisk C - „wolnostojące” i „hostowane” - aw środowiskach hostowanych funkcje opisane w standardach definiowane jako dostępne. W systemach wbudowanych środowisko C jest zwykle wolnostojące, więc możesz nie mieć procedur bibliotecznych lub możesz uniknąć używania niektórych i używać własnych zamienników.
10

Biblioteka wykonawcza to biblioteka, która jest automatycznie kompilowana dla każdego uruchamianego programu w C. Wersja biblioteki, której użyjesz, zależy od kompilatora, platformy, opcji debugowania i opcji wielowątkowości.

Dobry opis różnych opcji dostępnych w bibliotekach wykonawczych: http://www.davidlenihan.com/2008/01/choosing_the_correct_cc_runtim.html

Zawiera funkcje, o których normalnie nie myślisz, że wymagają biblioteki do wywołania:

  • malloc
  • enum, struct
  • abs, min
  • zapewniać

Microsoft ma ładną listę swoich funkcji biblioteki wykonawczej:

http://msdn.microsoft.com/en-us/library/2aza74he(VS.71).aspx

Dokładna lista funkcji będzie się różnić w zależności od kompilatora, więc w przypadku iOS można uzyskać inne funkcje, takie jak dispatch_async () lub NSLog ().

arinmorf
źródło
1
Czy struct i enum to naprawdę biblioteka uruchomieniowa?
Dean P
6

Jeśli używasz narzędzia takiego jak Dependency Walker na pliku wykonywalnym skompilowanym z C lub C ++, zobaczysz, że jedna z bibliotek DLL, od których jest zależny, to MSVCRT.DLL. To jest biblioteka Microsoft C Runtime Library. Jeśli przyjrzysz się dokładniej plikowi MSVCRT.DLL za pomocą DW, zobaczysz, że są tam wszystkie funkcje, takie jak printf (), puts (0, gets (), atoi () itp.


źródło
6
Tylko wtedy, gdy podczas kompilowania tego pliku wykonywalnego środowisko wykonawcze C zostało połączone dynamicznie. Jeśli było połączone statycznie, chodzik zależności pokaże nic
Eli Bendersky
4

myślę, że definicja Microsoftu naprawdę oznacza:

Wdrożenie przez firmę Microsoft standardowej biblioteki wykonawczej C zapewnia ...

Andrey
źródło
3

Istnieją trzy formy biblioteki wykonawczej języka C dostarczanej z zestawem Win32 SDK:

* LIBC.LIB is a statically linked library for single-threaded programs.
* LIBCMT.LIB is a statically linked library that supports multithreaded programs.
* CRTDLL.LIB is an import library for CRTDLL.DLL that also supports multithreaded programs. CRTDLL.DLL itself is part of Windows NT. 

32-bitowa edycja Microsoft Visual C ++ zawiera również te trzy formy, jednak CRT w bibliotece DLL nosi nazwę MSVCRT.LIB. Biblioteka DLL podlega redystrybucji. Jego nazwa zależy od wersji VC ++ (np. MSVCRT10.DLL lub MSVCRT20.DLL). Należy jednak pamiętać, że MSVCRT10.DLL nie jest obsługiwany na Win32s, podczas gdy CRTDLL.LIB jest obsługiwany na Win32s. MSVCRT20.DLL jest dostępny w dwóch wersjach: jednej dla Windows NT i drugiej dla Win32.

zobacz: http://support.microsoft.com/?scid=kb%3Ben-us%3B94248&x=12&y=9

Michael
źródło