GCC 能够通过__attribute__((weak))
. 我想在用户可以在其应用程序中覆盖的静态库中使用弱符号。GCC 风格的弱符号可以让我这样做,但我不知道它是否可以用 Visual Studio 完成。
Visual Studio 是否提供类似的功能?
GCC 能够通过__attribute__((weak))
. 我想在用户可以在其应用程序中覆盖的静态库中使用弱符号。GCC 风格的弱符号可以让我这样做,但我不知道它是否可以用 Visual Studio 完成。
Visual Studio 是否提供类似的功能?
你可以做到,这是 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")
MSVC++__declspec(selectany)
涵盖了弱符号的部分功能:它允许您使用外部链接定义多个相同的符号,指示编译器选择几个可用符号中的任何一个。但是,我认为 MSVC++ 没有任何东西可以涵盖弱符号功能的另一部分:在库中提供“可替换”定义的可能性。
顺便说一句,这让人想知道对标准可替换::operator new
和::operator delete
函数的支持如何在 MSVC++ 中工作。
MSVC 过去的行为是,如果在 .obj 文件和 .lib 中定义符号,它将使用 .obj 文件中的符号而不会发出警告。我记得它还可以处理符号在多个库中定义的情况,它将使用库中列表中第一个命名的库。
我不能说我已经尝试过一段时间了,但是如果他们改变了这种行为(尤其是 .obj 定义的符号会覆盖 .lib 文件中的符号),我会感到惊讶。
我知道的唯一方法。将每个符号放在单独的库中。具有覆盖的用户对象也必须组合到库中。然后将所有内容链接到一个应用程序。用户库必须指定为输入文件,您的库必须使用/DEFAULTLIB:
选项传输到链接器。
没有与此属性等效的 MS-VC。请参阅http://connect.microsoft.com/VisualStudio/feedback/details/505028/add-weak-function-references-for-visual-cc。我要提出一些可怕的建议:在这里阅读它的目的:http ://www.kolpackov.net/pipermail/notes/2004-March/000006.html它本质上是定义函数,如果它们的符号存在,被使用,否则,不是,所以......
为什么不为此目的使用预处理器,并提出“如果你需要这样做”的巨大警告?(我不喜欢推荐预处理器)。
例子:
#ifdef USE_MY_FUNCTION
extern void function();
#endif
#ifdef
然后在应用程序逻辑中适当地调用,由语句包围。如果您的静态库已链接,作为链接过程的一部分,请调整定义以定义 USE_MY_FUNCTION。
不是很直接的等价物并且非常丑陋,但它是我能想到的最好的。
从这里:
...如果在不咨询库的情况下可以满足所需的符号,则不会使用库中的 OBJ。这使您可以通过将符号显式放置为 OBJ 来覆盖库中的符号。您还可以覆盖库中的符号,以将其放在另一个库中,该库在您要覆盖的库之前进行搜索。但是您不能在显式 OBJ 中覆盖符号,因为它们是初始条件的一部分。
这种行为是由链接器采用的算法引起的。
所以简而言之,要覆盖一个函数,
使用 GCC,您必须使用__attribute__((weak))
. 您不能依赖目标文件在链接器中的输入顺序来决定使用哪个函数实现。
使用 VS 工具链,您可以依赖对象/lib 文件的顺序,并且必须将函数的实现放在实现原始函数的 LIB 之前。您可以将您的实现作为 OBJ 或 LIB。