2016-04-09 3 views
1

Ich habe folgende Situation bei der Verwendung GCC: SituationWie kann man eine Bibliothek statisch verknüpfen, die dynamisch eine andere Bibliothek verknüpft?

Ich habe eine dynamische Bibliothek mit dem Namen A.DLL, die korrekt und Links stellen zusammen und bilden LIBA.A.

Nun, ich habe eine andere statischen Bibliothek mit dem Namen LIBB.A, die eine Funktionsdefinition hat, dieafunc() von A.DLL verwendet. Dies kompiliert und verbindet auch korrekt und erzeugt LIBB.A.

Jedoch, wenn ich bin mit LIBB.A in einem anderen Programm PROGC.C an das ausführbare Programm PROGC.EXE, GCC verknüpfen können nicht mit LIBA.A zu A.DLL zu kompilieren.

Es gibt den Fehler: undefined reference to afunc().

Ich versuchte Art der folgenden Aktionen ausführen:

gcc PROGC.C -o PROGC.EXE -lLIBB.A -Wl,-Bdynamic -lLIBA.A ... 

Aber nichts funktioniert erfolgreich zu verknüpfen.

Meine Frage ist, ob das überhaupt möglich ist? Wenn ja, wie geht das? Wenn nein, warum nicht?

(. Vielen Dank im Voraus)

+0

vielleicht verwenden Sie nicht die gleiche Aufrufkonvention !!! – milevyo

+0

Wie hast du deine libb.a gebaut? – jdarthenay

+0

@jdarthenay Ich benutze folgendes um libb.a zu erstellen: 'gcc.exe ... -c B.c -o B.o' und' ar.exe -r -s LIBB.A B.o '. Wie von @milevyo gefordert, verwende ich jedoch keine explizite Aufrufkonvention in einer der Bibliotheken. Ist das ein Problem? P.S. Ich baue alles mit dem gleichen Compiler. –

Antwort

1

Hier ist ein Beispiel tut, die Sie versuchen zu tun:

ah:

#ifndef A_H 
#define A_H 

#ifdef BUILD_A_DLL 
#define EXPORT __declspec(dllexport) 
#else 
#define EXPORT __declspec(dllimport) 
#endif 

#ifdef __cplusplus 
extern "C" 
{ 
#endif 

extern EXPORT void __cdecl print_a_version(); 

#ifdef __cplusplus 
} 
#endif 

#endif 

ac:

#define BUILD_A_DLL 

#include "a.h" 

#include <stdio.h> 

EXPORT void __cdecl print_a_version() 
{ 
    printf("A: v1.0\n"); 
} 

bh:

#ifndef B_H 
#define B_H 

extern void print_b_version(); 

#endif 

b.c:

#include "b.h" 

#include <stdio.h> 

#include "a.h" 

void print_b_version() 
{ 
    print_a_version(); 
    printf("B: v1.0\n"); 
} 

stackoverflow.c:

#include "b.h" 

int main() 
{ 
    print_b_version(); 

    return 0; 
} 

Make-Datei (für mingw-64):

CC=GCC 
AR=ar 
WINVER=0x0400 
CFLAGS=-Wformat -std=gnu99 -Wall -Werror -DWINVER=$(WINVER) -std=gnu99 
LDFLAGSDLL=-shared -Wl,--out-implib,liba.a 
LDFLAGS=-L. -lb -la 

all:a.dll libb.a stackoverflow.exe 

a.dll:a.o 
    $(CC) $(CFLAGS) -o a.dll a.o $(LDFLAGSDLL) 

a.o:a.c a.h 
    $(CC) $(CFLAGS) -c a.c 

libb.a:b.o 
    $(AR) -rs libb.a b.o 

b.o:b.c b.h a.h 
    $(CC) $(CFLAGS) -c b.c 

stackoverflow.exe:stackoverflow.o libb.a 
    $(CC) $(CFLAGS) -o stackoverflow.exe stackoverflow.o $(LDFLAGS) 

stackoverflow.o:stackoverflow.c b.h 
    $(CC) $(CFLAGS) -c stackoverflow.c 

mrproper:clean 
    for %%i in (a.dll liba.dll libb.o stackoverflow.exe) do if exist %%i del %%i 

clean: 
    for %%i in (a.o b.o stackoverflow.o) do if exist %%i del %%i 

.PHONY:all clean mrproper 

Dies funktioniert für mich.

Edit: Wichtiger Hinweis - die Reihenfolge der -l Flags ist sehr wichtig. Mit LDFLAGS=-L. -la -lb schlägt das Erstellen von "stackoverflow.exe" fehl.

+0

Ich sehe meinen Fehler in der Reihenfolge der Verknüpfung, weil es auch andere Bibliotheken gab. –