2010-02-18 18 views
30

GCC tiene la capacidad de hacer un enlace de símbolo débilmente a través de __attribute__((weak)). Quiero utilizar un símbolo débil en una biblioteca estática que los usuarios pueden anular en su aplicación. Un símbolo débil de estilo GCC me permitiría hacer eso, pero no sé si se puede hacer con Visual Studio.Vinculación débil de estilo GCC en Visual Studio?

¿Visual Studio ofrece una función similar?

+1

Consulte [Biblioteca estática de Windows con funciones predeterminadas] (http://stackoverflow.com/questions/5097961/windows-static-library-with-default-functions). ¿Es esto lo que intentas lograr? – brady

+0

Consulte la [respuesta de Michael Burr] (http://stackoverflow.com/a/2290843/321013) - MSVC realmente * predeterminado * a este comportamiento. Si anula un símbolo que ya está definido en una lib de dependencia, el símbolo en '.lib' se ignorará silenciosamente. –

Respuesta

13

MSVC++ tiene __declspec(selectany) que cubre parte de la funcionalidad de los símbolos débiles: le permite definir múltiples símbolos idénticos con enlaces externos, dirigiendo al compilador para elegir cualquiera de los muchos disponibles. Sin embargo, no creo que MSVC++ tenga nada que cubra la otra parte de la funcionalidad de símbolo débil: la posibilidad de proporcionar definiciones "reemplazables" en una biblioteca.

Esto, por cierto, hace que uno se pregunte cómo funciona la compatibilidad con las funciones estándar reemplazables ::operator new y ::operator delete en MSVC++.

+0

¿Tiene MSVC++ algo así como esta macro que funciona con 'main()', para permitir que cualquier código que incluya * este * invalide 'main()'? – mcandre

+0

':: operator new' se envía como código objeto dentro' nothrownew.obj'. Supongo que el CRT usa un concepto similar al ['__fltused'-trick] (http://blogs.msdn.com/b/oldnewthing/archive/2013/01/08/10383017.aspx) para obtener el código objeto en el módulo a menos que se haya definido en otro lugar. Las reglas del vinculador clásico para OBJ y LIB se describen en [The Old New Thing] (http://blogs.msdn.com/b/oldnewthing/archive/2013/01/09/10383325.aspx). – IInspectable

0

Una forma de hacerlo sería implementarlo manualmente a través de LoadLibrary y GetProcAddress.

+0

desagradable y un montón de repetición ... suspiro C++: P –

+1

De hecho. Hace un código bastante feo. –

+1

La función débil estará en una biblioteca estática. ¿Funcionarían esas funciones sin DLL? –

3

No hay un MS-VC equivalente a este atributo. Ver http://connect.microsoft.com/VisualStudio/feedback/details/505028/add-weak-function-references-for-visual-c-c. Voy a sugerir algo horrible: leyendo su propósito aquí: http://www.kolpackov.net/pipermail/notes/2004-March/000006.html es esencialmente para definir funciones que, si sus símbolos existen, se usan, de lo contrario, no lo son, así que ...

¿Por qué no usar pre -procesador para este propósito, con la gran advertencia de "si necesita hacer esto en absoluto"? (No soy partidario de recomendar pre-procesador).

Ejemplo:

#ifdef USE_MY_FUNCTION 
    extern void function(); 
#endif 

luego llamar adecuadamente en la lógica de la aplicación, rodeado de #ifdef declaraciones. Si su biblioteca estática está vinculada, como parte del proceso de vinculación, modifique las definiciones para definir USE_MY_FUNCTION.

No es exactamente un equivalente directo y muy feo, pero es lo mejor que se me ocurre.

7

MSVC solía comportarse de manera que si un símbolo se define en un archivo .obj y .lib, usaría el que está en el archivo .obj sin previo aviso. Recuerdo que también manejaría la situación donde el símbolo está definido en múltiples libs, usaría el de la biblioteca nombrada primero en la lista.

No puedo decir que intenté esto por un tiempo, pero me sorprendería si cambiaran este comportamiento (especialmente que los símbolos .obj definidos anulen símbolos en archivos .lib).

+2

Una breve prueba con VS 2010 RC indica que el comportamiento que describí todavía está allí. –

58

Puede hacerlo, aquí es un ejemplo en 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

Esta es una respuesta correcta. ¿Puedes encontrar alguna documentación para respaldarlo? –

+21

Es una característica no documentada. Me encontré con esto accidentalmente mientras navegaba por el código fuente msvcrt. – Ringo

3

La única forma que conozco. Coloque cada símbolo en una biblioteca separada. Los objetos de usuario con anulaciones también se deben combinar con la biblioteca. Luego, vincula todo junto a una aplicación. La biblioteca de usuario debe especificarse como archivo de entrada, su lib debe transferirse al enlazador utilizando la opción /DEFAULTLIB:.

Cuestiones relacionadas