57 Stimmen

GCC-Stil schwache Verknüpfung in Visual Studio?

GCC hat die Fähigkeit, ein Symbol schwach über __attribute__((weak)) zu verknüpfen. Ich möchte ein schwaches Symbol in einer statischen Bibliothek verwenden, das Benutzer in ihrer Anwendung überschreiben können. Ein GCC-Stil schwaches Symbol würde es mir ermöglichen, das zu tun, aber ich weiß nicht, ob es mit Visual Studio gemacht werden kann.

Bietet Visual Studio eine ähnliche Funktion?

1 Stimmen

Siehe Windows-Statikbibliothek mit Standardfunktionen. Ist das das, was Sie erreichen möchten?

0 Stimmen

Siehe die Antwort von Michael Burr - MSVC verwendet tatsächlich standardmäßig dieses Verhalten. Wenn Sie ein Symbol überschreiben, das bereits in einer Abhängigkeitsbibliothek definiert ist, wird das Symbol in der .lib stillschweigend ignoriert.

0 Stimmen

VC++ bietet keine explizite Möglichkeit, Symbole als schwach zu deklarieren - aber es gibt zwei Alternativen, die nahe kommen. Überprüfen: ofekshilon.com/2014/02/10/linker-weak-symbols

99voto

Ringo Punkte 989

Du kannst es schaffen, hier ist ein Beispiel in C:

/*
 * pWeakValue MUSS eine externe Konstante sein, die auf pDefaultWeakValue aliasiert wird,
 * wenn keine echte Benutzerdefinition vorhanden ist, dank der
 * alternatename Direktive.
 */

extern const char * pWeakValue;
extern const char * pDefaultWeakValue = NULL;

#pragma comment(linker, "/alternatename:_pWeakValue=_pDefaultWeakValue")

1 Stimmen

Dies ist eine korrekte Antwort. Können Sie einige Dokumentationen finden, um sie zu unterstützen?

41 Stimmen

Es handelt sich um eine nicht dokumentierte Funktion. Ich bin zufällig darauf gestoßen, während ich den Quellcode von msvcrt durchsuchte.

0 Stimmen

@Ringo Wenn das pWeakValue bereits definiert ist, kann es dann immer noch durch die alternatename Option ersetzt werden?

19voto

AnT Punkte 300728

MSVC++ hat __declspec(selectany), das einen Teil der Funktionalität von schwachen Symbolen abdeckt: Es ermöglicht Ihnen, mehrere identische Symbole mit externer Verknüpfung zu definieren und den Compiler anzuweisen, eines von mehreren verfügbaren auszuwählen. Ich glaube jedoch nicht, dass MSVC++ etwas hat, das den anderen Teil der Funktionalität von schwachen Symbolen abdecken würde: die Möglichkeit, austauschbare Definitionen in einer Bibliothek bereitzustellen.

Dies lässt übrigens jemanden darüber nachdenken, wie die Unterstützung für standardmäßig austauschbare ::operator new und ::operator delete Funktionen in MSVC++ funktioniert.

0 Stimmen

Hat MSVC++ so etwas wie dieses Makro, das mit main() funktioniert, um es einem beliebigen dieser Datei zu ermöglichen, main() zu überschreiben?

2 Stimmen

::operator new wird als Objektcode innerhalb von nothrownew.obj ausgeliefert. Ich gehe davon aus, dass das CRT ein ähnliches Konzept wie den __fltused-Trick verwendet, um den Objektcode in das Modul zu ziehen, es sei denn, er wurde anderweitig definiert. Die klassischen Linkerregeln für OBJs und LIBs sind im Artikel The Old New Thing beschrieben.

16voto

Michael Burr Punkte 320591

MSVC verhielt sich so, dass es, wenn ein Symbol in einer .obj-Datei und einer .lib-Datei definiert ist, das in der .obj-Datei ohne Warnung verwendet wurde. Ich erinnere mich, dass es auch mit der Situation umgehen würde, wenn das Symbol in mehreren Bibliotheken definiert ist und das in der als erstes in der Liste genannten Bibliothek verwendet wird.

Ich kann nicht sagen, dass ich das in letzter Zeit ausprobiert habe, aber ich würde überrascht sein, wenn sie dieses Verhalten geändert hätten (besonders dass in .obj definierte Symbole Symbole in .lib-Dateien überschreiben).

3 Stimmen

Ein kurzer Test mit VS 2010 RC zeigt, dass das von mir beschriebene Verhalten immer noch vorhanden ist.

1 Stimmen

Auf eine gewisse Weise ziehe ich dieses Verhalten dem schwachen Attribut vor. Dies war meines Wissens nach schon immer das Verhalten in MS-Compilern (habe MS-Compiler seit 1988 (C5.0) verwendet). Ich war verwirrt, als ich dies vor ein paar Jahren in GCC entdeckt habe. Ich denke, es ist logisch, das erste Vorkommen der Funktion zu verwenden, das beim Verlinken gefunden wird, obwohl darauf geachtet werden muss, dass die verlinkte Funktion tatsächlich diejenige ist, die man denkt.

0 Stimmen

Warum kann Microsoft dies nicht mehr explizit machen? Und ich kann kein offizielles Dokument finden, das dieses Verhalten beschreibt. Ich frage mich, ob dies absichtlich oder versehentlich geschieht...

5voto

denis Punkte 41

Der einzige Weg, den ich kenne. Platzieren Sie jedes Symbol in einer separaten Bibliothek. Benutzerobjekte mit Überschreibungen müssen ebenfalls in eine Bibliothek zusammengefasst werden. Verknüpfen Sie dann alle miteinander zu einer Anwendung. Die Benutzerbibliothek muss als Eingabedatei angegeben werden, Ihre Bibliotheken müssen mit der /DEFAULTLIB:-Option an den Linker übertragen werden.

4voto

smwikipedia Punkte 56976

Von hier:

... Wenn ein benötigtes Symbol ohne Konsultation einer Bibliothek erfüllt werden kann, dann wird das OBJ in der Bibliothek nicht verwendet. Dies ermöglicht es Ihnen, ein Symbol in einer Bibliothek zu überschreiben, indem Sie es explizit in ein OBJ platzieren. Sie können auch ein Symbol in einer Bibliothek überschreiben, indem Sie es in eine andere Bibliothek setzen, die vor derjenigen durchsucht wird, die Sie überschreiben möchten. Aber Sie können kein Symbol in einem expliziten OBJ überschreiben, da diese Teil der Anfangsbedingungen sind.

Dieses Verhalten resultiert aus dem Algorithmus, den der Linker verwendet.

Also kurz gesagt, um eine Funktion zu überschreiben,

  • Mit GCC müssen Sie __attribute__((weak)) verwenden. Sie können sich nicht auf die Eingabereihenfolge von Objektdateien in den Linker verlassen, um zu entscheiden, welche Funktionsimplementierung verwendet wird.

  • Mit dem VS-Toolchain können Sie sich auf die Reihenfolge der Objekt-/Bibliotheksdateien verlassen und Sie müssen Ihre Implementierung der Funktion vor der LIB platzieren, die die Originalfunktion implementiert. Und Sie können Ihre Implementierung als OBJ oder LIB platzieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X