2010-02-18 16 views
30

GCC ha la capacità di creare un collegamento simbolico debole tramite __attribute__((weak)). Voglio usare il simbolo debole in una libreria statica che gli utenti possono sovrascrivere nella propria applicazione. Un simbolo debole in stile GCC mi consentirà di farlo, ma non so se si può fare con Visual Studio.Collegamento debole stile GCC in Visual Studio?

Visual Studio offre funzionalità simili?

+1

Vedere [Libreria statica di Windows con funzioni predefinite] (http://stackoverflow.com/questions/5097961/windows-static-library-with-default-functions). È questo che stai cercando di ottenere? – brady

+0

Vedere la [risposta di Michael Burr] (http://stackoverflow.com/a/2290843/321013) - MSVC in realtà * si imposta automaticamente su questo comportamento. Se si sostituisce un simbolo già definito in una lib di dipendenza, il simbolo in ".lib" verrà ignorato silenziosamente. –

risposta

13

MSVC++ ha __declspec(selectany) che copre parte della funzionalità dei simboli deboli: consente di definire più simboli identici con il collegamento esterno, indirizzando il compilatore a scegliere uno dei vari disponibili. Tuttavia, non penso che MSVC++ abbia qualcosa che possa coprire l'altra parte della debole funzionalità dei simboli: la possibilità di fornire definizioni "sostituibili" in una libreria.

Questo, a proposito, ci si chiede come il supporto per le funzioni sostituibili standard ::operator new e ::operator delete funzioni in MSVC++.

+0

MSVC++ ha qualcosa di simile a questa macro che funziona con 'main()', per consentire a qualsiasi codice incluso * questo * di sovrascrivere 'main()'? – mcandre

+0

':: operator new' viene fornito come codice oggetto all'interno di' nothrownew.obj'. Presumo che il CRT utilizzi un concetto simile a ['__fltused'-trick] (http://blogs.msdn.com/b/oldnewthing/archive/2013/01/08/10383017.aspx) per ottenere il codice oggetto nel modulo a meno che non sia stato definito altrove. Le regole del linker classico per OBJ e LIB sono descritte in [The Old New Thing] (http://blogs.msdn.com/b/oldnewthing/archive/2013/01/09/10383325.aspx). – IInspectable

0

Un modo per farlo sarebbe implementarlo manualmente tramite LoadLibrary e GetProcAddress.

+0

brutto e un sacco di piastre ... sigh C++: P –

+1

Infatti. Fa un po 'di brutto codice. –

+1

La funzione debole si troverà in una libreria statica. Queste funzioni funzionerebbero senza DLL? –

3

Non esiste un equivalente MS-VC per questo attributo. Vedi http://connect.microsoft.com/VisualStudio/feedback/details/505028/add-weak-function-references-for-visual-c-c. Ho intenzione di suggerire qualcosa di orribile: leggendo lo scopo qui: http://www.kolpackov.net/pipermail/notes/2004-March/000006.html è essenzialmente per definire funzioni che, se i loro simboli esistono, vengono utilizzati, altrimenti, non lo sono, quindi ...

Perché non utilizzare -processore per questo scopo, con l'enorme avvertenza di "se hai bisogno di fare questo a tutti"? (Non sono un fan di raccomandare il pre-processore).

Esempio:

#ifdef USE_MY_FUNCTION 
    extern void function(); 
#endif 

quindi richiamate in modo appropriato nella logica dell'applicazione, circondato da #ifdef istruzioni. Se la libreria statica è collegata, come parte del collegamento in corso, modificare le definizioni per definire USE_MY_FUNCTION.

Non proprio un equivalente diretto e molto brutto, ma è il meglio che riesco a pensare.

7

MSVC utilizzato per comportarsi in modo tale che se un simbolo è definito in un file .obj e un .lib, utilizzerà quello sul file obj senza preavviso. Ricordo che gestiva anche la situazione in cui il simbolo è definito in più librerie e userebbe quello nella libreria nominata per prima nella lista.

Non posso dire di averlo provato da un po ', ma sarei sorpreso se avessero modificato questo comportamento (specialmente che i simboli definiti .obj sovrascrivono i simboli nei file .lib).

+2

Un breve test con VS 2010 RC indica che il comportamento che ho descritto è ancora lì. –

58

Puoi farlo, ecco un esempio in C:

/* 
* pWeakValue MUST be an extern const variable, which will be aliased to 
* pDefaultWeakValue if no real user definition is present, thanks to the 
* alternatename directive. 
*/ 

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

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

Questa è una risposta corretta. Riesci a trovare qualche documentazione per il backup? –

+21

È una funzionalità non documentata. Mi sono imbattuto casualmente durante la navigazione nel codice sorgente di msvcrt. – Ringo

3

L'unico modo che conosco. Posiziona ciascun simbolo in una libreria separata. Anche gli oggetti utente con sostituzioni devono essere combinati alla libreria. Quindi collega tutti insieme a un'applicazione. La libreria utente deve essere specificata come file di input, la tua lib deve essere trasferita al linker usando l'opzione /DEFAULTLIB:.