Was ist die Wirkung von extern "C" in C++?
Was genau macht putting extern "C"
in C++ - code zu tun?
Beispiel:
extern "C" {
void foo();
}
Ich möchte Ihnen in diesem Artikel: http://www.agner.org/optimize/calling_conventions.pdf Es sagt viel mehr über die Aufrufkonvention und der Unterschied zwischen Compiler.
Auf der Spitze von meinem Kopf, es sagt dem compiler zu kompilieren, der Umfang von code mit C, gegeben, dass Sie einen cross-compiler. Auch, es bedeutet, dass Sie eine Cpp-Datei, in dem Sie haben, dass
können wir dann schließen Sie die andere Weise herum? Dies entspricht dem aktuellen Konsens, der gerade in der Nähe von "Qualität" und nicht als Datum von: meta.stackexchange.com/questions/147643/..., Da "Qualität" ist nicht messbar, gehe ich gerade durch upvotes. 😉 Wahrscheinlich geht es um die Frage traf den besten Neuling Google-keywords in den Titel. Lassen Sie mich wissen, wenn Sie denken, dass Sie sind nicht wirklich dupliziert.
Ich denke, man sollte Flagge.
OK. Hast du in der Nähe dieser Weise, weil Sie glauben der andere ist besser gebildet, oder vor allem, weil das Datum?
Auf der Spitze von meinem Kopf, es sagt dem compiler zu kompilieren, der Umfang von code mit C, gegeben, dass Sie einen cross-compiler. Auch, es bedeutet, dass Sie eine Cpp-Datei, in dem Sie haben, dass
foo()
Funktion.können wir dann schließen Sie die andere Weise herum? Dies entspricht dem aktuellen Konsens, der gerade in der Nähe von "Qualität" und nicht als Datum von: meta.stackexchange.com/questions/147643/..., Da "Qualität" ist nicht messbar, gehe ich gerade durch upvotes. 😉 Wahrscheinlich geht es um die Frage traf den besten Neuling Google-keywords in den Titel. Lassen Sie mich wissen, wenn Sie denken, dass Sie sind nicht wirklich dupliziert.
Ich denke, man sollte Flagge.
OK. Hast du in der Nähe dieser Weise, weil Sie glauben der andere ist besser gebildet, oder vor allem, weil das Datum?
InformationsquelleAutor Litherum | 2009-06-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
extern "C" macht eine Funktion-Namen in C++, 'C' - Verknüpfung (compiler nicht zerfleischen der name), so dass client C-code verlinken können (ich.e) Ihre Funktion mit einem 'C' - compatible-header-Datei enthält nur die Deklaration der Funktion. Ihre definition einer Funktion enthalten ist, die in einem binären format (kompiliert wurde durch Ihre C++ - compiler), die der client 'C' - linker wird dann link zu, mit dem 'C' Namen.
Da C++ das überladen von Funktionsnamen und C nicht, wird die C++ - compiler nicht nutzen Sie einfach den Namen der Funktion als eine eindeutige id zu verlinken, so dass es verstümmelt den Namen, indem Sie Informationen über die Argumente. Ein C-compiler muss nicht zerfleischen der name, da kann man nicht überlasten-Funktion Namen in C. Wenn Sie feststellen, dass eine Funktion extern "C" - Bindung in C++, der C++ - compiler nicht hinzufügen argument/parameter geben Informationen zu den verwendeten Namen für die Verknüpfung.
Nur damit Sie wissen, können Sie "C" Bindung an jede einzelne Deklaration/definition explizit oder verwenden Sie einen block, um der Gruppe eine Sequenz von Deklarationen/Definitionen, um eine bestimmte Bindung:
Wenn Sie kümmern sich um die Formalitäten, in der Sie aufgelistet sind, die in Abschnitt 7.5 von den C++03-standard, hier eine kurze Zusammenfassung (mit Betonung auf extern "C"):
alle Funktionstypen, Funktionsnamen und Variablennamen haben eine Sprache, die VerknüpfungSiehe Richards Kommentar: Nur Funktionsnamen und Variablennamen mit externe Bindung haben eine Sprache, die Verknüpfungextern "C" erzwingt eine Funktion haben externe Bindung (nicht statisch)Siehe Richards Kommentar: 'statische' innen 'extern "C" " ist gültig; eine Entität so erklärt hat, die interne Verlinkung, also nicht eine Sprache, die Verknüpfungversuchen Sie nicht, den link-code eingebaut mit verschiedenen C++ - Compiler, auch wenn die Verweise sind alle "extern " C"'. Es gibt oft Unterschiede zwischen den layouts von Klassen oder die Mechanismen zur Behandlung von Ausnahmen, oder die Mechanismen verwendet, um die Variablen initialisiert sind, bevor Sie verwenden, oder andere solche Unterschiede, plus müssen Sie möglicherweise zwei separate C++ run-time support libraries (eine für jeden compiler).
vielen Dank, Sie machen gute Punkte. Ich meine nicht, zu ermutigen, mit verschiedenen C++ - Compiler durch die Verwendung von extern "C". Vielmehr hoffte ich schlage vor, dass, wenn Sie nicht schriftlich etwas würde müssen verbunden werden, um von einem anderen C++ - compiler, die Sie wahrscheinlich nicht brauchen, extern "C".
"extern " C" erzwingt eine Funktion haben externe Bindung (nicht statische)' ist falsch. 'static' innen 'extern "C" " ist gültig; eine Entität so erklärt hat, die interne Verlinkung, also nicht eine Sprache, die Verknüpfung.
'Funktion alle Typen, Funktionsnamen und Variablennamen haben eine Sprache, die Verknüpfung', ist auch falsch. Nur Funktionsnamen und Variablennamen mit externe Bindung haben eine Sprache, die Verknüpfung.
InformationsquelleAutor Faisal Vali
Wollte nur hinzufügen, ein wenig info, da ich es noch nicht gesehen haben gebucht noch.
Wirst du sehr oft sehen-code in C-Header etwa so:
Was dies erreicht ist, die es erlaubt, Sie zu benutzen, dass die C-header-Datei mit dem C++ - code, weil das makro "__cplusplus" definiert werden. Aber Sie können auch immer noch verwenden Sie es mit Ihren legacy C-code, wo auch das makro ist NICHT definiert, damit es nicht zu sehen, die eindeutig C++ - Konstrukt.
Obwohl, ich habe auch gesehen, C++ - code wie:
die ich mir vorstellen führt viel die gleiche Sache.
Nicht sicher, welcher Weg besser ist, aber ich habe gesehen, beide.
Der C++ - compiler wird sich nach unmangled Namen auch, weil es sah
extern "C"
in der Kopfzeile). Es funktioniert Super, die diese Technik verwendet, viele Male.Das ist nicht richtig, die erste ist auch gut. Es ist, ignoriert der C # - compiler und hat die gleiche Wirkung wie der zweite in C++. Der compiler könnte nicht weniger interessieren, ob es auf
extern "C"
vor oder nach enthält es die header. Durch die Zeit, erreicht der compiler, es ist nur ein langer Strom von analysierten text sowieso.Nein, ich glaube, du hast wurden die betroffenen durch einen anderen Fehler in der Quelle, weil das, was Sie beschreiben, ist falsch. Keine version von
g++
hat etwas falsch gemacht, für jeden Gegner, zu jeder Zeit-in den letzten 17 Jahren mindestens. Der springende Punkt, der das erste Beispiel ist, dass es egal ist, ob Sie eine C-oder C++ - compiler, kein name mangling durchgeführt werden wird, für die Namen in derextern "C"
block."welches ist besser" - sicher, die erste Variante ist besser: Es erlaubt, einschließlich der header, die direkt, ohne weitere Anforderungen, die beide in C-und C++ - code. Der zweite Ansatz ist ein workaround für C-Header der Autor vergessen hat, die C++ Wachen (kein problem, wenn diese Hinzugefügt werden, danach geschachtelte extern "C" Erklärungen sind accepteded...).
InformationsquelleAutor UncaAlby
In jedem C++ - Programm, alle nicht-statischen Funktionen sind dargestellt in der Binär-Datei als Symbole. Diese Symbole sind Besondere Zeichenketten, die eindeutig identifiziert eine Funktion in das Programm.
In C, die symbol-name ist der gleiche wie der name der Funktion. Dies ist möglich, da in C keine zwei nicht-statische Funktionen können den gleichen Namen haben.
Weil C++ erlaubt das überladen und hat viele features, die C nicht — wie bei Klassen, member-Funktionen, exception - Spezifikationen ist es nicht möglich, verwenden Sie einfach den Namen der Funktion als der symbol-name. Um das zu beheben, C++, verwendet sogenannte name mangling, die verwandelt den Namen der Funktion und alle notwendigen Informationen (wie die Anzahl und Größe der Argumente) in einigen seltsam aussehenden Zeichenfolge verarbeitet nur durch den compiler und linker.
Also, wenn Sie eine Funktion angeben werden extern C der compiler nicht, führt die name manglings mit es und es kann direkt
über seine symbol-name der Funktion.
Das ist praktisch, während Sie mit
dlsym()
unddlopen()
für den Aufruf solcher Funktionen.ja. Es ist im wesentlichen unmöglich, im Allgemeinen Fall zu dlopen() einen C++ shared library nur eine header-Datei und wählen Sie die richtige Funktion zum laden. (Auf x86, es ist ein veröffentlichter name-mangling-Spezifikation in form des Itanium ABI, die alle x86-Compilern die ich kenne verwenden zu zerfleischen C++ - Funktionsnamen, aber nichts in der Sprache, die dies erfordert.)
InformationsquelleAutor sud03r
Dekompilieren einer
g++
erzeugten Binär-zu sehen, was Los istmain.cpp
Kompilieren mit GCC 4.8 Linux ELF Ausgabe:
Dekompilieren der symbol-Tabelle:
Die Ausgabe enthält:
Interpretation
Sehen wir, dass:
ef
undeg
gespeichert wurden, in Symbole mit dem gleichen Namen wie im codedie anderen Symbole wurden entstellt. Lassen Sie uns unmangle Sie:
Fazit: beide der folgenden symbol-Typen wurden nicht entstellt:
Ndx = UND
), zur Verfügung gestellt werden, die zur link-oder zur Zeit von einem anderen Objekt-DateiSo müssen Sie
extern "C"
sowohl beim Aufruf:g++
zu erwarten unmangled Symbole produziert vongcc
g++
zu generieren unmangled Symbole fürgcc
zu verwendenDinge, die nicht funktionieren in extern C
Wird es offensichtlich, dass jede C++ - Funktion, die erfordert, dass die name manglings funktioniert nicht innerhalb
extern C
:Minimaler ausführbarer C von C++ Beispiel
Der Vollständigkeit halber und für die newbs gibt, siehe auch: Wie der Einsatz von C-source-Dateien in ein C++ - Projekt?
Aufrufen von C von C++ ist ziemlich einfach: jede C-Funktion hat nur eine mögliche, nicht entstellten symbol, so dass keine zusätzliche Arbeit erforderlich ist.
main.cpp
c.h
c.c
Run:
Ohne
extern "C"
den link nicht mit:weil
g++
erwartet, finden Sie eine entstelltef
, diegcc
nicht produzieren.Beispiel auf GitHub.
Minimal lauffähigen C++ von C Beispiel
Aufrufen von C++ aus ist das ein bisschen schwieriger: wir haben manuell zu erstellen, nicht entstellten Versionen von jeder Funktion, die wir wollen, zu entlarven.
Hier zeigen wir, wie zu setzen C++ - Funktion überlastungen zu C.
main.c
cpp.h
cpp.cpp
Run:
Ohne
extern "C"
schlägt es mit:weil
g++
generiert entstellte Symbole, diegcc
nicht finden können.Beispiel auf GitHub.
Getestet in Ubuntu 18.04.
extern "C" {
hilft Ihnen, rufen Sie unmangled C-Funktionen aus C++ - Programmen sowie unmangled C++ - Funktionen innerhalb von C-Programmen, die anderen Antworten nicht so offensichtlich ist, und 2), weil Sie zeigen verschiedene Beispiele von jedem. Danke!Das ist das beste, gut erklärte Antwort hier. Dank
Ich mag diese Antwort sehr
InformationsquelleAutor Ciro Santilli 新疆改造中心996ICU六四事件
C++ verstümmelt Funktionsnamen erstellen einer Objekt-orientierten Sprache eine prozedurale Sprache
Meisten Programmiersprachen sind nicht gebaut auf der Spitze des bestehenden Programmiersprachen. C++ baut auf der Spitze des C, und ferner ist eine Objekt-orientierte Programmier-Sprache gebaut, aus einer prozeduralen Programmiersprache, und aus diesem Grund sind C++ - Ausdrücke wie
extern "C"
die rückwärts-Kompatibilität mit C.Betrachten wir das folgende Beispiel:
Einen C-compiler nicht kompilieren Sie das Beispiel oben, weil die gleiche Funktion
printMe
definiert ist zweimal (auch wenn Sie unterschiedliche Parameter habenint a
vschar a
).Einem C++ compiler kompilieren Sie das obige Beispiel. Es kümmert sich nicht, dass
printMe
definiert ist doppelt.Dies ist, weil ein C++ - compiler implizit benennt (mangles) Funktionen basierend auf Ihren Parametern. In C wurde diese Funktion nicht unterstützt. Allerdings, wenn C++ gebaut wurde, über C, die Sprache, die entworfen wurde, um Objekt-orientiert und benötigt zur Unterstützung der Fähigkeit zu erstellen, die verschiedenen Klassen mit Methoden (Funktionen) mit dem gleichen Namen, und das überschreiben von Methoden (Methode überschreiben) basierend auf unterschiedlichen Parametern.
extern "C"
sagt "don' T mangle-C-Funktion Namen"Jedoch vorstellen, dass wir ein Erbe C-Datei mit dem Namen "Eltern.c", die
include
s-Funktion Namen aus anderen legacy-C-Dateien "Eltern.h", "Kind.h", etc. Wenn das Erbe "Eltern.c" - Datei ist eine C++ - compiler, dann wird der Funktion werden Namen verstümmelt, und Sie werden nicht mehr mit der Funktion angegebenen Namen in "Eltern.h", "Kind.h", etc - also die Funktion von Namen in diesen externen Dateien müssen auch verstümmelt. Mangeln Funktionsnamen über ein Komplexes C-Programm, die mit vielen Abhängigkeiten, kann es zu gebrochenen code, so ist es vielleicht zweckmäßig sein, um eine keyword-die können feststellen, dass der C++ - compiler nicht zu zerfleischen name einer Funktion.Den
extern "C"
Schlüsselwort sagt ein C++ - compiler nicht zu 'zerfleischen' (umbenennen) C-Funktionsnamen. Beispiel:extern "C" void printMe(int a);
extern "C"
wenn wir nur einendll
- Datei? Ich meine, wenn wir nicht eine header-Datei und nur eine source-Datei (nur-Implementierungen) und die Verwendung der Funktion über Funktionszeiger. in diesem Zustand, den wir nur von Funktionen (unabhängig von deren Namen).für mich ist Sie es genagelt Recht! direkt in den Kopf.
InformationsquelleAutor tfmontague
Ändert es die Verknüpfung einer Funktion in einer Weise, dass die Funktion aufrufbar ist, C. In der Praxis bedeutet das, dass der name der Funktion ist nicht entstellt.
Entstellt ist der Begriff in der Regel verwendet... glaube nicht, dass ich je gesehen habe 'dekoriert' mit dieser Bedeutung.
hier heißt Dekoration en.wikipedia.org/wiki/Name_mangling
InformationsquelleAutor Employed Russian
Nicht alle C-header-kompatibel gemacht werden kann mit C++ allein durch die Verpackung in extern "C". Wenn Bezeichner in einem C-header-Konflikt mit einem C++ - Schlüsselwörter C++ - compiler wird sich beschweren, über diese.
Zum Beispiel habe ich gesehen, wie Sie den folgenden code ein Fehler in einer g++ :
Irgendwie Sinn macht, aber es etwas im Auge zu behalten bei der Portierung von C-code nach C++.
extern "C"
Mittel zu verwenden, C-Verknüpfung, wie beschrieben von anderen Antworten. Es bedeutet nicht, dass auf "compile der Inhalt als C", oder so etwas.int virtual;
ungültig ist in C++ und durch unterschiedliche Verknüpfung nicht ändern.... oder mode im Allgemeinen, beliebigen code mit syntax-Fehler werden nicht kompiliert.
natürlich, allerdings mit "virtuellen" als Bezeichner in C ist kein syntax-Fehler. Ich wollte nur zeigen, dass man nicht automatisch mit beliebiger C-header in C++, indem Sie extern "C" um ihn herum.
InformationsquelleAutor Sander Mertens
Informiert er den C++ - compiler, um die Namen dieser Funktionen in einem C-style bei der Verlinkung, denn die Namen der Funktionen zusammengestellt, die in C und C++ sind unterschiedliche bei der Verlinkung der Bühne.
InformationsquelleAutor Mark Rushakoff
extern "C" gemeint ist, erkannt zu werden, die von einem C++ - compiler, und informiert den compiler, dass die erwähnte Funktion ist (oder zu sein), zusammengestellt im C-Stil. So dass, während die Verknüpfung, link auf die richtige version der Funktion aus C.
InformationsquelleAutor Flami
Benutzte ich "extern " C"', bevor Sie für die dll(dynamic link library) - Dateien zu machen etc. main () - Funktion "exportierbar", so kann es später in ein anderes ausführbares Programm von der dll.
Vielleicht ein Beispiel, wo ich nützlich sein kann.
DLL
EXE
extern "C"
und__declspec(dllexport)
unabhängig sind. Der ehemalige Steuerelemente, symbol, Dekoration, letztere ist verantwortlich für die Erstellung einer export-Eintrag. Exportieren Sie können ein symbol mit C++ - Namensergänzung genauso gut. Neben völlig fehlt der Punkt, diese Frage, gibt es andere Fehler im code-Beispiel wie gut. Zum einenmain
aus der DLL exportiert nicht deklarieren einen Wert zurück. Oder Aufruf-Konvention, für diese Angelegenheit. Beim importieren werden Sie Attribut eine zufällige Aufrufkonvention (WINAPI
), und das falsche symbol für die 32-bit-builds (sollte_main
oder_main@0
). Sorry, -1.Das hat nur wiederholt, dass Sie nicht wissen, was Sie tun, aber tun es auf diese Weise zu arbeiten scheint für Sie, für einige nicht offengelegte Liste der Zielplattformen. Sie hat nicht die Probleme anzusprechen, die ich wuchs in meinem vorherigen Kommentar. Dies ist immer noch eine down-vote, wegen, völlig falsch ist (es gibt mehr, das passte nicht in einen einzigen Kommentar).
Posting eine Antwort auf Stack Overflow Art der impliziert, dass Sie wissen, was Sie tun. Dies ist zu erwarten. Für Ihren Versuch "um zu verhindern, dass stack-Korruption auf "ausführen",": Ihre Funktion Unterschrift gibt einen Rückgabewert vom Typ
void*
, aber Ihre Umsetzung nicht etwas zurückzugeben. Das Fliegen wirklich gut...Wenn Sie etwas umsetzen, dass scheint zu arbeiten, durch reines Glück, dann Sie deutlich machen, nicht wissen, was Sie tun (Ihre "Arbeit" Beispiel fällt in diese Kategorie). Es ist Undefiniertes Verhalten, und erscheinen zur Arbeit eine gültige form des undefinierten Verhalten. Es ist noch nicht definiert. Ich würde mich sehr freuen, wenn Sie ausgeübt, mehr Sorgfalt in der Zukunft. Teil werden könnte, dass die Streichung der vorgeschlagenen Antwort.
Sie interpretieren eine Funktion, die nichts zurückgibt, eine Funktion, die einen pointer zurück. Es ist reines Glück, dass x86 ist sehr nachsichtig mit Bezug auf nicht übereinstimmende Signaturen von Funktionen und insbesondere die Rückgabe-Werte der integral-Typ. Dein code funktioniert nur zufällig. Wenn Sie nicht einverstanden sind, müssen Sie erklären, warum Ihr code funktioniert zuverlässig.
InformationsquelleAutor SturmCoder
extern "C"
ist die Verknüpfung Spezifikation die verwendet wird, um Aufruf von C-Funktionen in der Cpp-Quelldateien. Wir können Aufruf von C-Funktionen, Variablen schreiben, & include Header. Funktion deklariert ist extern entity & es ist außerhalb von Ihnen definiert werden. Syntax istTyp 1:
Typ 2:
zB:
InformationsquelleAutor Yogeesh H T
Diese Antwort ist für die ungeduldigen/Fristen zu erfüllen, nur einen Teil/einfache Erklärung ist unten:
So
in C++, mit die name manglings eindeutig Identitäten jede Funktion
in C, auch ohne name mangling eindeutig Identitäten jede Funktion
Ändern das Verhalten von C++, das heißt, um anzugeben, dass die name manglings sollte nicht geschehen für eine bestimmte Funktion, die Sie verwenden können extern "C" vor den Namen der Funktion, aus welchem Grund auch immer, wie das exportieren einer Funktion mit einem bestimmten Namen aus einer dll, die für die Nutzung durch seine Kunden.
Lesen anderer Antworten, für genauere/mehr richtige Antworten.
InformationsquelleAutor Manohar Reddy Poreddy
Beim mischen von C und C++ (d.h., ein. Aufruf der C-Funktion aus C++; und b. aufrufen von C++ - Funktion aus C), die C++ name mangling Ursachen verknüpfen Probleme. Technisch gesehen, dieses Problem tritt nur auf, wenn die aufgerufene Funktionen wurden bereits für Sie zusammengestellt binären (wahrscheinlich eine *.eine Bibliothek-Datei) mit den entsprechenden compiler.
Also müssen wir mit extern "C" zu deaktivieren, der name mangling in C++.
InformationsquelleAutor Trombe