2011-01-11 19 views
8

Neben Verschieben der hello()-Funktion in eine andere Quelldatei (.cpp) oder Umbenennen der Funktion. Gibt es andere Methoden, um den Verbindungsfehler zu vermeiden?Wie vermeidet man mehrere Definitionsfehler?

staticLibA.h

#ifndef _STATIC_LIBA_HEADER 
#define _STATIC_LIBA_HEADER 

int hello(void); 
int hello_staticLibA_only(void); 

#endif 

staticLibA.cpp

#include "staticLibA.h" 

int hello(void) 
{ 
    printf("\nI'm in staticLibA\n"); 
    return 0; 
} 

int hello_staticLibA_only(void) 
{ 
    printf("\nstaticLibA: hello_staticLibA_only\n"); 
    return 0; 
} 

output:

g++ -c -Wall -fPIC -m32 -o staticLibA.o staticLibA.cpp 
ar -cvq ../libstaticLibA.a staticLibA.o 
a - staticLibA.o 

staticLibB.h

#ifndef _STATIC_LIBB_HEADER 
#define _STATIC_LIBB_HEADER 

int hello(void); 
int hello_staticLibB_only(void); 

#endif 

staticLibB.cpp

#include "staticLibB.h" 

int hello(void) 
{ 
    printf("\nI'm in staticLibB\n"); 
    return 0; 
} 

int hello_staticLibB_only(void) 
{ 
    printf("\nstaticLibB: hello_staticLibB_only\n"); 
    return 0; 
} 

output:

g++ -c -Wall -fPIC -m32 -o staticLibB.o staticLibB.cpp 
ar -cvq ../libstaticLibB.a staticLibB.o 
a - staticLibB.o 

main.cpp

extern int hello(void); 
extern int hello_staticLibA_only(void); 
extern int hello_staticLibB_only(void); 

int main(void) 
{ 
    hello(); 
    hello_staticLibA_only(); 
    hello_staticLibB_only(); 
    return 0; 
} 

output:

g++ -c -o main.o main.cpp 
g++ -o multipleLibsTest main.o -L. -lstaticLibA -lstaticLibB -lstaticLibC -ldl -lpthread -lrt 
./libstaticLibB.a(staticLibB.o): In function `hello()': 
staticLibB.cpp:(.text+0x0): multiple definition of `hello()' 
./libstaticLibA.a(staticLibA.o):staticLibA.cpp:(.text+0x0): first defined here 
collect2: ld returned 1 exit status 
make: *** [multipleLibsTest] Error 1 

Antwort

1

Die Verknüpfungsfehler bezieht sich speziell auf Hallo. Dies zeigt sich, weil beide Bibliotheken Definitionen von "Hallo" bereitstellen. Es gibt hier keinen weiteren Verknüpfungsfehler. entweder

können Sie setzen hallo in einer separaten Bibliothek haben hallo in einer separaten Bibliothek befinden, oder einfach nur die ausführbare Datei Link gegen eine hallo Objektdatei [hello.o]

11

Da Sie scheinen beide Bibliotheken zu besitzen, es ist unklar, warum die Funktion nicht umbenennen ...

In Ihrem main, haben Sie diese Zeile:

hello(); 

Was erwarten Sie hier passieren, wenn Sie die Verknüpfung Fehler machen weggehen? Sollte es die Implementierung in LibA oder LibB aufrufen? Es ist wie eine sehr schlechte Idee, sich auf die Reihenfolge zu verlassen, in der Sie die Bibliotheken an den Linker übergeben, um festzustellen, welche Funktion verknüpft wird. In einem realen Beispiel, was passieren würde, wenn Ihre hello_staticLibB_only Funktion hello() aufrufen würde? Es könnte am Ende Aufruf der Version der Funktion, die in der anderen Bibliothek ...

Wie Sie g++ verwenden, sollten Sie in Betracht ziehen, Ihre Bibliothek Funktionen in eine namespace (sie sind entworfen, um Ihnen zu helfen, diese Art zu vermeiden des Namenskonflikts). Dadurch können sowohl Ihr Code als auch der Linker den Unterschied zwischen den Methoden feststellen.

Nach diesem Ansatz für LibA, würden Sie haben:

staticLibA.h

#ifndef _STATIC_LIBA_HEADER 
#define _STATIC_LIBA_HEADER 

// Declare namespace to keep library functions together 
namespace LibA { 
    int hello(void); 
    int hello_staticLibA_only(void); 
} 

#endif 

staticLibA.cpp

#include "staticLibA.h" 
#include <stdio.h> 

// Indicate that contained function definitions belong in the LibA namespace 
namespace LibA { 
    int hello(void) 
    { 
     printf("\nI'm in staticLibA\n"); 
     return 0; 
    } 

    int hello_staticLibA_only(void) 
    { 
     printf("\nstaticLibA: hello_staticLibA_only\n"); 
     return 0; 
    } 
} 

main.cpp

// These declarations would usually be in a header... but I've left 
// them here to match your sample code... 

// declare relevant functions to belong to the LibA namespace 
namespace LibA{ 
    extern int hello(void); 
    extern int hello_staticLibA_only(void); 
} 

// declare relevant functions from LibB (note they are not 
// in a namespace) 
extern int hello(void); 
extern int hello_staticLibB_only(void); 

int main(void) 
{ 
    // Explicitly call the hello from LibA 
    LibA::hello(); 
    // Call the other library function (also from LibA) 
    LibA::hello_staticLibA_only(); 

    // Call library functions from LibB (note they don't require a namespace 
    // because I haven't updated it to have one) 
    hello(); 
    hello_staticLibB_only(); 
    return 0; 
} 
+0

+1: Nicht viel mehr zu dem Thema zu sagen. – rubenvb

Verwandte Themen