2011-07-25 16 views
10

Muszę zweryfikować coś, co do którego mam wątpliwości. Jeśli biblioteka współdzielona (.dll) jest napisana w C, ze standardem C99 i skompilowana pod kompilatorem. Powiedz MinGw. Z mojego doświadczenia wynika, że ​​jest ona kompatybilna z binariami, a zatem może być użyta z dowolnego innego kompilatora. Powiedz MS Visual Studio. Mówię z mojego doświadczenia, ponieważ próbowałem tego z powodzeniem więcej niż raz. Ale muszę sprawdzić, czy to jest reguła.Crosscompiler Kompatybilność binarna w C

I dodatkowo chciałbym zapytać, czy rzeczywiście tak jest, dlaczego biblioteki napisane w C, na przykład openCV, nie dostarczają skompilowanych plików binarnych dla każdego innego systemu operacyjnego? Wiem, że oczywistym powodem byłoby ustawienie wszystkich parametrów podczas kompilacji, ale poza tym nie ma żadnego prawa?

EDYCJA: Dodaję dodatkowe pytanie, które widzę jako logiczne przedłużenie oryginału. Czy nie w ten sposób można stworzyć zamkniętą bibliotekę źródłową? Ponieważ opcja podania źródła wychodzi poza okno, jedynym rozwiązaniem jest podanie plików binarnych. W takim przypadku zapewnienie binariów dla tylu architektur, jak to możliwe, jest pożądanym rezultatem, przy czym C jest oczywistym wyborem dla najlepszego przenoszenia pomiędzy systemami i kompilatorami. Dobrze?

+0

Bardzo interesujące pytanie. Co dziwne, nigdy tak naprawdę nie dałem tej głębokiej myśli, mimo że byłem facetem Debuggera na początku i w połowie lat 80-tych w świecie UN * X. Oczywiście najczęściej używałem tabeli symboli jako przewodnika, ale wciąż mogą być pytania o bit-packing w strukturach i przesuwanie argumentów na stosie. Zgaduję, że w tym świecie większość kodu jest/została skompilowana z jedną lub drugą wersją albo kompilatora producenta, albo GCC, więc istniała nieodłączna spójność, ale nie jest to dokładnie to, o co prosisz. –

Odpowiedz

6

W konkretnym przypadku kompilatorów języka C (MSVC i GCC/MinGW) w świecie Windows, masz rację przy założeniu zgodności binarnej. Można połączyć DLL interfejsu C skompilowany przez GCC do programu w Visual Studio. W ten sposób projekty C99, takie jak ffmpeg, pozwalają programistom pisać aplikacje z Visual Studio. Trzeba tylko stworzyć bibliotekę importu z lib.exe znalezioną w Microsoft Toolchain z biblioteki DLL. Lub vice versa, używając pexportów mingw.org lub lepszego, narzędzia gendef mingw-w64, można stworzyć bibliotekę importu GCC dla biblioteki DLL stworzonej przez MSVC.

Ta poręczna interoperacyjność rozpada się po wejściu w świat interfejsu C++, w którym ABI MSVC i GCC jest różne i niekompatybilne. Może zadziałać, ale nie może, nie ma żadnych gwarancji i nie podejmuje się (obecnie) żadnych wysiłków, aby to zmienić. Ponadto informacje debugowania są oczywiście różne, dopóki ktoś nie napisze generatora/programu piszącego do debugowania w GCC, który jest kompatybilny z debugerem MSVC (oczywiście wraz z obsługą GDB).

Nie sądzę, że C99 specjalnie zmienia cokolwiek w deklaracjach funkcji lub w sposobie obsługi argumentów w definicjach symboli, więc nie powinno tu być problemu.

Należy zauważyć, że jak powiedział Vijay, nadal istnieje różnica w architekturze, więc biblioteki x86 nie można użyć podczas łączenia z biblioteką AMD64.


Aby odpowiedzieć również na dodatkowe pytanie dotyczące plików binarnych o zamkniętym kodzie źródłowym i dystrybucji wersji dla wszystkich dostępnych kompilatorów/architektur.

W ten sposób utworzysz plik binarny o zamkniętym kodzie źródłowym. Oprócz biblioteki importowania bardzo ważne jest również ukrycie eksportu z biblioteki DLL, dzięki czemu biblioteka DLL sama w sobie nie nadaje się do łączenia (jeśli nie chcesz, aby kod klienta korzystał z prywatnych funkcji w bibliotece, zobacz na przykład dane wyjściowe z dumpbin /exports na MSOffice DLL, dużo ukrytych tam rzeczy). Możesz osiągnąć to samo z GCC (uważam, nigdy nie użyłem lub wypróbowałem) używając rzeczy takich jak __attribute(hidden) itd ...

Niektóre punkty szczególne kompilatora:

  1. MSVC pochodzi z czterech (a właściwie tylko trzy pozostały w nowszych wersjach) przez różne biblioteki wykonawcze/MT,/MD i/LD. Oprócz tego musisz zapewnić kompilację dla każdej wersji programu Visual Studio (w tym Service Packs), aby zapewnić kompatybilność. Ale to jest plik binarny o zamkniętym źródle i Windows dla ciebie ...

  2. GCC nie ma tego problemu; MinGW zawsze łączy się z msvcrt.dll dostarczonym przez Windows (od Windows 98), równoważnym z/MD (i może także równoważnikiem biblioteki debugowania z/MDd). Ale istnieją dwie wersje MinGW (mingw.org i mingw-w64), które nie gwarantują zgodności binarnej. Ta ostatnia jest bardziej kompletna, ponieważ zapewnia opcje 64-bitowe, a także 32-bitowe i zapewnia bardziej kompletny zestaw nagłówków/bibliotek (w tym znaczną część DirectX i DDK).

+0

Dzięki za odpowiedź, oczywiście różne architektury wymagają rekompilacji z innym kompilatorem. Co rozumiesz przez interfejs C++? Czy nie jest tak samo we wszystkich kompilatorach, że możesz wywołać kod C z zewnętrznej biblioteki, jeśli ją otakujesz w zewnętrznym "C" {...}? Moje pytanie dotyczy także tworzenia biblioteki zamkniętych źródeł. Będziesz musiał dostarczyć binaria tylko C, co prawda najlepsza przenośność binarna byłaby oczywistym wyborem, prawda? – Lefteris

+0

Lefteris: zobacz moją aktualizację, a tak, 'extern" C "{...}' jest tym, czego potrzebujesz, aby zapewnić interfejs C. Interfejs C++ można utworzyć, kompilując za pomocą g ++, i pomijając tę ​​część, która pozwala na kopiowanie nazwy, co jest jednym z ograniczników show dla kompatybilności między kompilatorami. – rubenvb

+0

Dziękuję bardzo za odpowiedź, była dość szczegółowa. Jeśli chodzi o wymieszanie nazw, to wiem, niestety dostałem to w twarz wiele razy w przeszłości, a to spowodowało, że w kilku moich projektach wróciłem do C z powodu przenośności. – Lefteris

2

Wspólna biblioteka lub biblioteka dll skompilowana do konkretnej architektury może być połączona z aplikacjami skompilowanymi przez inne kompilatory, które są ukierunkowane na tę samą architekturę. (Przez architekturę rozumiem kombinację procesora/OS). Jednak programista biblioteki nie jest w stanie skompilować się ze wszystkimi możliwymi architekturami. Ponadto, gdy biblioteka jest dystrybuowana w formie źródłowej, użytkownicy mogą budować pliki binarne zoptymalizowane pod kątem ich specyficznych wymagań.

4

Ogólną zasadą jest, że jeśli kombinacja OS/CPU posiada standardowe ABI, a jeśli to ABI jest wystarczająco silny dla danego języka, większość kompilatorów będzie wynikać, że ABI iw rezultacie będą binarnie kompatybilny, pozwalając możesz połączyć biblioteki (współdzielone lub statyczne) skompilowane z różnymi kompilatorami do programów skompilowanych z innymi kompilatorami.

Problem polega na tym, że większość ABI jest dość słaba - projektowane są w językach niskiego poziomu, takich jak C i FORTRAN, i sięgają czasów sprzed języków obiektowych, takich jak C++. Nie mają więc wsparcia dla takich rzeczy jak przeciążanie funkcji, operatory zdefiniowane przez użytkownika, wyjątki, globalne kontrargumenty i destruktory, funkcje wirtualne, dziedziczenie i takie, które są potrzebne w C++.

Ten brak został rozpoznany, gdy zaprojektowano C++, dlatego też C++ ma extern "C" - co powoduje, że kompilator ogranicza się do standardowego ABI dla niektórych funkcji, jednocześnie wyłączając wszystkie dodatkowe funkcje C++, które ogólnie ABI nie obsługują .