Слабая связь GCC в Visual Studio?
GCC имеет возможность слабо сделать ссылку на символ через __attribute__((weak))
. Я хочу использовать слабый символ в статической библиотеке, которую пользователи могут переопределить в своем приложении. Слабый символ стиля GCC позволил мне сделать это, но я не знаю, можно ли это сделать с помощью visual studio.
Предлагает ли Visual Studio аналогичную функцию?
Ответы
Ответ 1
MSVС++ имеет __declspec(selectany)
, который охватывает часть функциональных возможностей слабых символов: он позволяет вам определять несколько идентичных символов с внешней связью, направляя компилятору на выбор любого из нескольких доступных. Однако я не думаю, что у MSVС++ есть что-то, что будет охватывать другую часть слабой функциональности символа: возможность предоставить "заменяемые" определения в библиотеке.
Это, BTW, заставляет задуматься, как поддержка стандартных сменных функций ::operator new
и ::operator delete
работает в MSVС++.
Ответ 2
Вы можете сделать это, вот пример в 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")
Ответ 3
MSVC привык вести себя так, что если символ определен в файле .obj и .lib, он будет использовать тот, который находится в файле .obj без предупреждения. Я помню, что он также справлялся бы с ситуацией, когда символ определен в нескольких библиотеках, он будет использовать тот, который находится в библиотеке с именем first в списке.
Я не могу сказать, что я пробовал это через некоторое время, но я был бы удивлен, если бы они изменили это поведение (особенно, что определенные символы .obj переопределили символы в .lib файлах).
Ответ 4
Нет эквивалента MS-VC для этого атрибута. См. http://connect.microsoft.com/VisualStudio/feedback/details/505028/add-weak-function-references-for-visual-c-c. Я собираюсь предложить что-то ужасное: прочитав его цель: http://www.kolpackov.net/pipermail/notes/2004-March/000006.html, по сути, нужно определить функции, которые, если их символы существуют, используются, в противном случае, нет, поэтому...
Почему бы не использовать предварительный процессор для этой цели, с огромным предостережением "если вам нужно это делать вообще"? (Я не поклонник предварительного процессора).
Пример:
#ifdef USE_MY_FUNCTION
extern void function();
#endif
тогда правильно вызовите логику приложения, окруженную операторами #ifdef
. Если ваша статическая библиотека связана в рамках процесса привязки, настройте определения для определения USE_MY_FUNCTION.
Не совсем прямой эквивалент и очень уродливый, но это лучшее, что я могу придумать.
Ответ 5
Единственный способ, который я знаю. Поместите каждый символ в отдельную библиотеку. Пользовательские объекты с переопределениями также должны быть объединены в библиотеку. Затем соедините все вместе с приложением. Пользовательская библиотека должна быть указана в качестве входного файла, ваша библиотека должна быть передана в компоновщик с помощью опции /DEFAULTLIB:
.
Ответ 6
Один из способов сделать это - выполнить его вручную через LoadLibrary и GetProcAddress.
Ответ 7
Pass /FORCE:MULTIPLE
для компоновщика.