Verknüpfen der kompilierten statischen C-Bibliothek mit dem C++-Programm

Lesezeit: 3 Minuten

Benutzer-Avatar
Prabu

Ich habe versucht, eine statische Bibliothek (kompiliert mit gcc) mit einem C++-Programm zu verknüpfen, und ich habe ‘undefinierte Referenz’ erhalten. Ich habe gcc und g ++ Version 4.6.3 auf einem Ubuntu 12.04-Servercomputer verwendet. Hier ist zum Beispiel die einfache Bibliotheksdatei für die faktorielle Methode:

mylib.h

#ifndef __MYLIB_H_
#define __MYLIB_H_

int factorial(int n);

#endif

mylib.c

#include "mylib.h"

int factorial(int n)
{
    return ((n>=1)?(n*factorial(n-1)):1);
}

Ich habe ein Objekt für diese mylib.c mit gcc erstellt:

gcc -o mylib.o -c mylib.c

Auch hier wurde die statische Bibliothek mit dem AR-Dienstprogramm aus der Objektdatei erstellt:

ar -cvq libfact.a mylib.o

Ich habe diese Bibliothek mit einem C-Programm (test.c) und einem C++-Programm (test.cpp) getestet.

Sowohl C- als auch C++-Programme haben denselben Rumpf:

#include "mylib.h"
int main()
{
    int fact = factorial(5);
    return 0;
}

Unter der Annahme, dass die statische Bibliothek libfact.a im Verzeichnis /home/test verfügbar ist, habe ich mein C-Programm ohne Probleme kompiliert:

gcc test.c -L/home/test -lfact

Beim Testen des C++-Programms wurde jedoch ein Link-Fehler ausgegeben:

g++ test.cpp -L/home/test -lfact

test.cpp:(.text+0x2f): undefined reference to `factorial(int)'
collect2: ld returned 1 exit status

Ich habe sogar versucht, den externen Befehl in test.cpp hinzuzufügen:

extern int factorial(int n) //added just before the main () function

Immer noch der gleiche Fehler.

  • Kann mir jemand sagen was ich hier falsch mache?
  • Gibt es etwas, das ich beim Erstellen der statischen Bibliothek übersehen habe?
  • Muss ich irgendetwas in meiner hinzufügen test.cpp damit es funktioniert?

  • Wenn ich SO-Fragen ohne Upvote sehe, zusammen mit einer 7-Upvote-Antwort, verstehe ich voll und ganz, wie dumm die Menschheit ist. Wie kann die Antwort relevant sein, wenn die Frage es nicht ist? Komm schon!

    – m-ric

    4. Juni 2014 um 19:01 Uhr

Benutzer-Avatar
John

Das Problem ist, dass Sie Ihrem C++-Programm nicht mitgeteilt haben, dass Fakultät in C geschrieben ist. Sie müssen Ihre test.h-Header-Datei ändern. So was

#ifndef __MYLIB_H_
#define __MYLIB_H_

#ifdef __cplusplus
extern "C" {
#endif

int factorial(int n);

#ifdef __cplusplus
}
#endif

#endif

Jetzt sollte Ihre Header-Datei sowohl für C- als auch für C++-Programme funktionieren. Siehe hier für Details.

Übrigens sind Namen, die einen doppelten Unterstrich enthalten, für den Compiler reserviert (das gilt auch für Namen, die mit einem Unterstrich und einem Großbuchstaben beginnen). #ifndef __MYLIB_H_ ist streng genommen illegal. Ich würde zu wechseln #ifndef MYLIB_H #define MYLIB_H

  • Ja, es funktioniert wie ein Zauber damit. Danke für den Link. Vielen Dank für das Hinzufügen von Informationen zum doppelten Unterstrich.

    – Prabu

    28. September 2013 um 6:29 Uhr


  • tolle erklärung. +1

    – kgui

    29. Januar 2017 um 3:45 Uhr


Obwohl die akzeptierte Antwort absolut richtig ist, dachte ich, ich würde nur eine Beobachtung hinzufügen. Einige Editoren haben Probleme mit der öffnenden/schließenden geschweiften Klammer und werden das Ganze einrücken extern "C" Geltungsbereich in der Kopfzeile. Wenn mylib.h ein Schlüsselheader für eine Bibliothek ist, könnten Sie Folgendes in Betracht ziehen:

#if defined (__cplusplus)
#define _MYLIB_INIT_DECL extern "C" {
#define _MYLIB_FINI_DECL }
#else
#define _MYLIB_INIT_DECL
#define _MYLIB_FINI_DECL
#endif

Alle anderen Header drin mylib Bibliothek, z. mylib_aux.hkann die Form haben:

#ifndef _MYLIB_AUX_H
#define _MYLIB_AUX_H

#include <mylib.h>

_MYLIB_INIT_DECL

... header content ...

_MYLIB_FINI_DECL

#endif /* _MYLIB_AUX_H */

Offensichtlich sind die Namen, die ich verwende, willkürlich, aber für mehrere Bibliotheksheader war dieser Ansatz für mich nützlich.

1205060cookie-checkVerknüpfen der kompilierten statischen C-Bibliothek mit dem C++-Programm

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy