2015-07-08 13 views
5

Próbuję użyć dwóch dużych, złożonych bibliotek algebry liniowej, które definiują wiele tych samych funkcji. Nie mogę przepisać (prawnie w jednym przypadku, ale technicznie w obu) żadnej z nich. Nazwijmy je "specjalnymi" i "normalnymi", ponieważ wywołuję tylko kilka funkcji specjalnych. Do funkcji zdefiniowanych w normal.h i tylko w niektórych przypadkach z konsekwentnie nazwać, zrobiłem coś takiego:Domyślny model łączenia w gcc 4.4 vs. gcc> 4.4

namespace special_space 
{ 
#include "special.h" // Defines foo() 
} 

#include "normal.h" // Defines foo() 

int main() { 
    foo();    // Calls foo() defined in normal.h 
    special_space::foo(); // Calls foo() defined in special.h 
} 

Z g ++ - 4.4, która była domyślną gdzie rozwijał ten kod kompiluje i linki bez ostrzeżeń i działa tak, jak bym tego oczekiwał i jak chcę. Wydaje się to być spójne na różnych platformach, w różnych środowiskach Linux, Unix i BSD. Ale! jeśli skompilować z g ++> 4.4, dostaję ostrzeżenia o wielokrotności foo() definicje:

w pliku special.h :: linia: kol: ostrzeżenie: deklaracja "void special_space :: foo() z języka C powiązanie [domyślnie włączone]

Wynikowy plik wykonywalny następnie segfaults na wywołanie special_space::foo(). Myślę/że określenie w specyfikacjach znalezionych w pliku special.h może rozwiązać ten problem, ale nie mogę zmienić pliku special.h. Więc co powinienem zrobić? Dokładniej:

1) Czy można bezpiecznie używać g ++ - 4.4? Jeśli tak - co zmieniło się w kolejnych wersjach i dlaczego?

2) Jeśli określenie modelu sprzężenia C++ naprawiłoby to, czy istnieje sposób, aby powiedzieć ld, aby go używać domyślnie?

3) Jeśli żaden z nich - czy istnieje inny sposób wywoływania funkcji z bibliotek, które definiują funkcje o tej samej nazwie?

+2

Czy obie funkcje mają początkowo C-link? Jeśli tak: [C funkcje wyłączają mangling nazwy] (http://stackoverflow.com/questions/9685994/c-extern-c-functions-inside-a-namespace) – WorldSEnder

+1

Spróbuj owijać oba obejmuje w ' #ifdef __cplusplus extern „C” { #endif #include normal.h #ifdef __cplusplus } #endif” – rost0031

+1

Jeśli nie można zmienić bibliotek potem już konkretny model sprzężeń i nie można tego zmienić. – nneonneo

Odpowiedz

1

Tak jak napisałem w komentarzu, owinąć nagłówki zawiera z

#ifdef __cplusplus 
extern "C" { 
#endif 

#include normal.h 

#ifdef __cplusplus 
} 
#endif 

zrobić z obu nagłówków.

Zasadniczo, ponieważ łączysz biblioteki c z C++, które wymieniają nazwę (to pozwala przeciążać), twoje połączenia z symbolami w twojej bibliotece były zniekształcane przez linker. #ifdef __cplusplus mówi łącznikowi, aby nie mangle nazwy dla tych konkretnych symboli funkcji.

Najlepiej byłoby, gdyby twórcy biblioteki uwzględnili to w swoich nagłówkach, ale wspomnieliście, że nie mają nad tym kontroli. Miałem podobny problem z wygenerowanym kodem. Musiałem zawinąć wszystkie moje nagłówki zawierające wygenerowany kod, aby umożliwić C++ wywołanie go.

To, czego nie wiem, to to, jak to działało bez tego. Zdecydowanie musiałem to zrobić, powracając do gcc < 4.4.

+0

Aby nazwać nazwy: problematyczne nagłówki pochodziły z GSL (gsl/gsl_linag.h i gsl/gsl_blas.h) i MKL firmy Intel (mkl.h i mkl_lapacke.h). – gerowam

Powiązane problemy