Mam program C++, który kompiluję z mingw (gcc dla Windows). Używanie wersji mingw TDM zawierającej gcc 4.4.1. Plik wykonywalny łączy się z dwoma plikami biblioteki statycznej (.a): Jedna z nich to biblioteka stron trzecich napisana w języku C; druga to napisana przeze mnie biblioteka C++, która używa biblioteki C, która dostarcza moje własne API C++ na wierzchu.Wiele definicji wbudowanych funkcji podczas łączenia bibliotek statycznych
(W mojej opinii, nadmierna) część funkcji biblioteki C jest zaimplementowana w funkcjach inline. Nie można pominąć funkcji wstawianych, gdy korzystasz z biblioteki biblioteki C, ale gdy próbuję połączyć to wszystko razem, otrzymuję komunikat o błędzie z linkami mówiącą, że istnieje wiele definicji wszystkich funkcji wbudowanych - oba mam wywoływane w mojej bibliotece opakowującej C++ i takie, których nie mam, w zasadzie wszystko, co zdefiniowano w nagłówku w nagłówkach, uzyskało funkcję utworzoną dla niego zarówno w bibliotece C, jak iw bibliotece C++.
Nie powoduje błędów w wielu definicjach, gdy pliki włączeń są używane wiele razy w różnych plikach .c lub .cpp w tym samym projekcie; Problem polega tylko na tym, że generuje jedną definicję na bibliotekę.
Jak/dlaczego kompilator generuje funkcje i symbole dla tych funkcji wbudowanych w obu bibliotekach? Jak zmusić go do zaprzestania generowania ich w moim kodzie? Czy istnieje narzędzie, które można uruchomić, aby usunąć duplikaty funkcji z pliku .a, lub sposób, aby linker zignorował wiele definicji?
(FYI, trzecia biblioteka zawiera wszystkie nagłówki #ifdef __cplusplus i extern "C" - w każdym razie, gdyby to był problem, nie spowodowałaby wielokrotnej definicji symbolu, spowodowałaby przeciwny problem ponieważ symbol byłby niezdefiniowany lub co najmniej inny.)
W szczególności błędy łącza NIE występują, jeśli łącza do bibliotek DLL biblioteki C strony trzeciej; jednak otrzymuję dziwne awarie środowiska wykonawczego, które wydają się mieć związek z moim kodem posiadającym własną wersję funkcji, które powinien wywoływać z biblioteki DLL. (Tak jakby kompilator tworzył lokalne wersje funkcji, których nie prosiłem).
Podobne wersje tego pytania zostały zadane wcześniej, jednak nie znalazłem odpowiedzi na moją sytuację w żadnej z tych sytuacji:
odpowiedź na to pytanie, że plakat został wielokrotnie definiowania zmienne, mój problem jest wielokrotnością definicja funkcji inline: Repeated Multiple Definition Errors from including same header in multiple cpps
to był program MSVC, ale używam MinGW; także, problem z plakatem w tym pytaniu był definicją konstruktora klasy C++ poza ciałem klasy w nagłówku, podczas gdy mój problem dotyczy funkcji C, które są wbudowane: Static Lib Multiple Definition Problem
Ten głupiec zmienił nazwę całego swojego kodu C na C++ pliki i jego kod C nie był C++ - bezpieczne: Multiple definition of lots of std:: functions when linking
ten był po prostu chcą wiedzieć, dlaczego naruszono zasadę jedna definicja nie wystąpił błąd: unpredictable behavior of Inline functions with different definitions
Zauważ, że C99 semantyka inline różnią się od jednego z C++: W C , jeśli jedno z deklaracji funkcji inline jest jawnie określone 'extern', tworzy zewnętrzną definicję - która nie jest już definicją śródliniową. Te zewnętrzne definicje nie mogą pojawić się wiele razy w programie. W C++ jawny 'extern' na takiej funkcji nie ma żadnego efektu. Najlepiej radzisz sobie z 'static inline' w C. –
Zwykle definicje funkcji inline są oznaczone jako" słabe "symbole, a linker powinien sam usuwać wszystkie duplikaty. – Omnifarious
Dzięki Johannesowi: przy użyciu definicji preprocesora, pliki nagłówkowe biblioteki C deklarują te funkcje "inline", jeśli znajdują się w plikach .c biblioteki C, i "extern inline", gdy są w moim projekcie. Ale nie jestem pewien, dlaczego to zrobili w ten sposób. Biblioteka C ma kod, który używa adresu funkcji jako unikalnej wartości klucza. Jako programista C++ uważam, że jako zła praktyka i naprawdę modlę się, że w ten sposób nie używali adresu funkcji inline. Czuję, że wśród tych komentarzy jest dość informacji, aby znaleźć odpowiedź, chociaż nadal nie mogę skompilować programu. – Dennis