extern C kann nicht auf Klassenebene verwendet werden?

8

Ich möchte nur bestätigen in Windows-Umgebung, VSTS 2008 + C ++ - Projekt, wir könnten nur extern C auf Funktionsebene anwenden, nicht auf Klassenebene anwenden können (so dass alle Mitgliedsfunktionen aus der Klasse den Namen der C-Sprache verwenden) ? Ich habe mehrere Möglichkeiten ausprobiert, aber immer Fehler kompilieren.

danke im voraus, George

    
George2 22.06.2009, 03:11
quelle

5 Antworten

11

Sie können extern "C" über einen sehr komplizierten (aber völlig legalen) Hack auf eine Member-Funktion anwenden:

%Vor%

Dies ist möglich gemäß ISO C ++ 03 9.3 [class.mfct] / 9:

  

Eine Memberfunktion kann mit einem typedef für einen Funktionstyp deklariert (aber nicht definiert) werden. Die resultierende member-Funktion hat genau den gleichen Typ, als wenn der Funktionsdeklarator explizit bereitgestellt würde, siehe 8.3.5.

Allerdings kauft Ihnen das wegen ISO C ++ 03 7.5 [dcl.link] / 4:

nichts wirklich
  

Eine C-Sprachverknüpfung wird für die Namen der Klassenmitglieder und der Mitgliedsfunktion ignoriert   Art der Klassenmitgliedsfunktionen.

    
Pavel Minaev 23.12.2009 00:58
quelle
5

extern "c" verwendet eine C-Style-Verknüpfung; Das heißt, der Name der RAW-Funktion wird von der Bibliothek ausgegeben. Da es sich um einen reinen Funktionsnamen handelt, kann keine der C ++ - Funktionen verwendet werden, einschließlich Methoden oder externen Datenmembern in Namespaces, Klassen, Strukturen oder Unionen.

Klärung : Strukturen und Vereinigungen sind in C, haben aber keine Mitgliedsfunktionen, daher können ihre Elementfunktionen in C ++ nicht im C-Stil exportiert werden (und die Struktur- und Vereinigungsdefinitionen müssen nicht exportiert werden) , da es bereits im Header steht)

    
Todd Gardner 22.06.2009 03:32
quelle
4

Ich fürchte, nicht. Aber wenn Sie ein Objekt von C ++ an C-Funktionen übergeben möchten, können Sie auf diesen Link verweisen: Ссылка

    
ZelluX 22.06.2009 03:33
quelle
3

Betrachten Sie einen Kommentar, den Sie auf eine vorherige Antwort gesetzt haben ("[M] y question ist nur, ob wir extern C auf Klassenebene anwenden könnten, so dass alle Funktionen in der Klasse automatisch C-style name mangling haben?", lautet die Antwort ist ' extern "C" funktioniert nicht ganz so.'

Syntaktisch kann extern "C" auf eine einzelne Anweisung eines durch Blocktrennzeichen getrennten Blocks angewendet werden:

%Vor%

Es ist üblich, extern "C" mit den entsprechenden #ifdef __cplusplus -Wachen für ganze C-Header zu verwenden.

Semantisch wird der tatsächliche Effekt der Anwendung von extern "C" nur auf "normale" (d. h. Nicht-Klassen-) Funktionen und Zeiger auf Funktionen angewendet. Natürlich können Sie es nicht auf eine C ++ Vorlage anwenden. Sie können es auch nicht auf Klassenmethoden anwenden (weil eine Klassenmethode wissen muss, an welchem ​​Objekt sie aufgerufen wurde, und C-Style-Verknüpfungen haben keine Möglichkeit, diese Informationen an die Funktion zu übergeben).

Es ist möglich, extern "C" auf Funktionen anzuwenden, die in einem Namespace vorhanden sind, aber die Namespace-Informationen verschwinden einfach, wenn sie über C verwendet werden.

Aktualisieren

Wenn Sie bereits eine Klasse haben (wir verwenden eine POD class zur Vereinfachung), und Sie möchten es von C aus nutzbar machen, müssen Sie extern "C" auf eine Funktion anwenden, die in C aufgerufen werden kann. Leider wird dies selbst in einfachen Fällen hässlich:

%Vor%

Mit gcc kompilieren Sie dies wie folgt:

  • die C ++ Datei: g++ try.cc -c -o try.o
  • die C-Datei: gcc try.c try.o

Es gibt ein paar wichtige Punkte:

  • Wenn Ihre C ++ - Datei hinter den Kulissen in die STL aufruft oder new oder delete (oder new[] oder delete[] ) aufruft, müssen Sie das endgültige Programm mit der C ++ - Laufzeitbibliothek (dem Befehl) verknüpfen Zeilenumschaltung dafür in gcc ist -lstdc++ .
  • Wahrscheinlich werden Sie beim Kompilieren des C- und C ++ - Codes identische Optimierungs-Flags übergeben (die Optimierung kann sich auf die Größe der Objekte auswirken, und wenn die Größe nicht übereinstimmt, können Sie in große Schwierigkeiten geraten) . Dito für Multithreading.
  • Sie können Ausnahmen verwenden, die Sie im C ++ - Code haben möchten, aber Sobald sie den C-Code überschritten haben, sind alle Wetten deaktiviert .
  • Wenn Sie etwas Komplexeres wollen, sollten Sie sich das PIMPL-Muster ansehen.
  • Wenn eine Struktur im C-Code nicht mehr im Geltungsbereich ist, wird der C ++ - Destruktor nicht aufgerufen (einige Compiler versprechen dies vielleicht, aber es ist kein Standard). Wenn Sie diese Objekte bereinigen müssen, müssen Sie eine externe "C" -Funktion aufrufen, die den Destruktor aufruft.

Um den Destruktor explizit aufzurufen:

%Vor%     
Max Lybbert 22.06.2009 04:02
quelle
2

Ummm ... extern "C" erzwingt C-Style-Verknüpfungen. Es kann nicht mit den Klassen AFAIK verwendet werden.

    
D.Shawley 22.06.2009 03:19
quelle

Tags und Links