Frage

Ich schrieb eine C ++ Funktion, dass ich aus einem C-Programm aufrufen müssen. Um es von C aufrufbaren, I angegebenen extern "C" auf der Funktion Erklärung . Ich habe dann den C ++ Code kompiliert, aber der Compiler (Dignus Systems / C ++) einen verstümmelten Namen erzeugt für die Funktion. So ist es offenbar nicht die extern "C" ehren.

Um dies zu beheben, habe ich extern "C" auf die Funktion Definition . Danach wird der Compiler einen Funktionsnamen generiert, die aus C aufrufbar ist.

Technisch muss der extern "C" nur auf der Funktionsdeklaration angegeben werden. Ist das richtig? (Die C ++ FAQ Lite hat ein gutes Beispiel dafür.) Sollten Sie auch auf der Funktionsdefinition angeben?

Hier ist ein Beispiel, dies zu zeigen:

/* ---------- */
/* "foo.h"    */
/* ---------- */

#ifdef __cplusplus
extern "C" {
#endif

/* Function declaration */
void foo(int);

#ifdef __cplusplus
}
#endif

/* ---------- */
/* "foo.cpp"  */
/* ---------- */

#include "foo.h"

/* Function definition */
extern "C"               // <---- Is this needed?
void foo(int i) {
  // do something...
}

Mein Problem kann das Ergebnis falsch Codierung etwas, oder ich kann einen Compiler Fehler gefunden haben. Auf jeden Fall wollte ich Stackoverflow konsultieren, um sicherzustellen, ich weiß, was technisch die „richtige“ Art und Weise ist.

War es hilfreich?

Lösung

Die ‚extern "C"‘ sollte nicht so lange auf der Funktion defintion erforderlich sein, wie die Erklärung zu besitzen und wird bereits bei der Erstellung des defintion gesehen. Die Norm ausdrücklich bestimmt, (7.5 / 5 Linkage Spezifikationen):

  

Eine Funktion kann ohne eine Verknüpfungsvorschrift deklariert werden, nachdem eine explizite Verknüpfung Spezifikation gesehen wurde; die Verknüpfung explizit in der früheren Anmeldung angegeben wird nicht durch eine solche Funktion Erklärung betroffen.

Allerdings habe ich im Allgemeinen setzen die ‚extern "C"‘ auf der Defintion als auch, weil es in der Tat eine Funktion mit extern „C“ Verknüpfung ist. Viele Leute hassen, wenn nicht notwendig, redundante Sachen auf Erklärungen sind (wie virtual auf Methode überschreibt setzen), aber ich bin nicht einer von ihnen.

Andere Tipps

Bearbeiten:
Scheint, als ob ich die Frage falsch verstanden hatte. Wie auch immer, ich versuchte:


// foo.cpp
/* Function definition */

#include "foo.h"

void foo(int i) {
 //do stuff
}
void test(int i)
{
// do stuff
}

// foo.h
#ifdef __cplusplus
extern "C" {
#endif

/* Function declaration */
void foo(int);

#ifdef __cplusplus
}
#endif

void test(int);

Mit Befehl nm die Symbole aus der kompilierte Datei anzuzeigen:


linuxuser$ nm foo.o
00000006 T _Z4testi
         U __gxx_personality_v0
00000000 T foo

Dies zeigt eindeutig, dass der Name der Funktion als extern „C“ deklariert wird, nicht entstellt und das extern „C“ Schlüsselwort ist nicht Definition erforderlich.
Wäre es würde unbrauchbar gewesen ++ Programme in C ohne extern „C“ geschrieben jeder C-Bibliothek-Code erforderlich.

Gerade diese Situation begegnet ... keine angenehme Erfahrung.

Das Folgende wurde in einem meiner c Dateien deklariert:

void unused_isr(void) {}
void ADC_IRQHandler(void)     __attribute__ ((weak, alias("unused_isr"))); 

Als nächstes irgendwo in einer cpp Datei I definiert:

void ADC_IRQHandler(void) {                                                                                  
    ...
}

Und ich vergaß die Vorwärts-Erklärung zu ändern:

void ADC_IRQHandler(void);

Es dauerte eine Weile, bis ich herausgefunden ich alles richtig in Bezug auf die AD-Wandlung zu tun, aber ich nicht „extern C“, um die Definition zu addieren!

extern "C" void ADC_IRQHandler(void) {                                                                                  
    ...
}

Nur meine zwei Cents, warum es könnte unter bestimmten Umständen nützlich sein, die Gewohnheit zu haben, um es auch auf die Definition hinzuzufügen.

ich denke, das muss hier geklärt werden, wie ich gerade ein ähnliches Problem hatte und es dauerte eine Weile, dies klar in meinem Kopf zu bekommen, nur Brooks Moses richtig auf diesem berühren, und ich denke, es muss mehr festgestellt werden, klar ...

Zusammenfassend kann der Header werfen Sie weg, alle der Compiler sieht, ist die CPP-Datei und wenn der Header nicht mit dem extern „C“ zurück in Ihre CPP enthalten (was ich sehe häufig), dann die extern „C“ müssen in der CPP-Datei irgendwo sein (entweder in der Definition oder eine andere Erklärung), so dass die CXX Compiler wissen, kann es mit C-Bindung zu machen, wird der Compiler über den Header sich nicht, nur den Linker.

Die extern "C" um die Definition ist nicht erforderlich. Sie können mit nur darum, es um die Erklärung wegzukommen. Ein Hinweis in Ihrem Beispiel ...

#ifdef __cplusplus
extern "C" {
#endif

/* Function declaration */
void foo(int);

#ifdef __cplusplus
}
#endif

Der Code sucht den Präprozessormakro „__cplusplus“.

Während es allgemein implementiert ist, abhängig von Ihrem Compiler kann diese oder nicht definiert werden kann. In Ihrem Beispiel verwenden Sie auch extern "C" um die Erklärung, aber es Sie nicht für die „__cplusplus“ Makro überprüft, weshalb ich vermute, es hat funktioniert, wenn Sie das tat.

Siehe die Kommentare unten -. Standard C ++ erfordert den __cplusplus Makro durch den Präprozessor definiert werden

Es sollte um beides sein. Der Compiler muss wissen, das C Symbolnamen und Aufrufkonventionen zu verwenden, wenn die Aufrufstellen kompiliert (die nur eine Erklärung sehen kann), und der Compiler muss auch wissen, das C Symbolnamen zu erzeugen und die C-Aufrufkonventionen verwenden, wenn die Kompilierung Funktionsdefinition selbst (die keine anderen Erklärungen sehen kann).

Wenn Sie nun eine extern-C-Deklaration, die von der Übersetzungseinheit, in der sichtbar ist die Definition vorhanden ist, können Sie möglicherweise mit wegzukommen das extern-C aus der Definition Weglassen, aber ich weiß nicht, so viel ist sicher.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top