在x64 DLL中强制名称修改

我正在将32位应用程序移植到64位。 该应用程序支持DLL的插件。 不幸的是,每个插件需要具有的强制函数之一称为FreeLibrary ,它当然与同名的kernel32 API冲突。 我的插件API使用FreeLibrary名称的原因是该应用程序源自FreeLibrary不与任何OS API冲突的不同平台。

但是,即使在使用FreeLibrary 32位Windows上也不是问题,因为32位DLL使用名称修改,即该函数存储为_FreeLibrary ,因此不会与kernel32 API冲突。

但是,在64位上,我现在遇到了一个问题,因为64位似乎没有使用名称修改。 在64位编译器创建一个名为FreeLibrary的符号,这当然与同名的kernel32 API冲突并拒绝链接,导致以下错误:

 Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. kernel32.lib(KERNEL32.dll) : error LNK2005: FreeLibrary already defined in test.o Creating library test.lib and object test.exp test.dll : fatal error LNK1169: one or more multiply defined symbols found 

因此,我想知道是否有任何方法强制x64 DLL使用32位的名称修改,以便我的DLL可以导出一个名为FreeLibrary的符号,而不与kernel32发生任何冲突?

或者还有其他解决方案可以解决这个问题吗?

我看到的唯一解决方案是将FreeLibrary重命名为不与我的应用程序的x64版本的OS API冲突的东西,但当然我想避免这种情况,因为它会降低我的应用程序的插件API的一致性。 如果可能的话,我想在所有平台和架构中保留FreeLibrary名称。

有任何想法吗? 我想如果在32位上有可能在DLL中使用像FreeLibrary这样的保留名称,那么应该有办法在64位上执行它,不应该在那里吗? 但我不明白……

我不会试图说服编译器破坏函数的名称。 那种方式就是疯狂。

为了澄清,您唯一的问题是链接插件DLL时的重复符号。 应用程序本身不应该关心函数的名称,因为它将通过GetProcAddress接收的函数指针调用插件入口点。

假设插件不需要调用kernel32.dll中实现的Windows API,您可以尝试从链接器命令中省略kernel32.dll。 (请参阅/NODEFAULTLIB选项。)如果kernel32.dll不是链接的一部分,则不应该发生冲突。

但这不起作用,因为/MT命令行中的/MT意味着您依赖于C运行时库,而C依赖于某些kernel32.dll API。 (另外,您确定要将插件链接到静态运行时库而不是DLL版本吗?)

所以剩下的选择是更改函数的名称。 这应该是微不足道的,因为无论如何你都在移植。 您甚至可以在编译插件时使用预处理器来破解名称,这样您就不需要更改其源代码:

 cl /EHsc /c /DFreeLibrary=Plugin_FreeLibrary /Fotest.o test.c 

然后更改应用程序中的GetProcAddress调用以查找Plugin_FreeLibrary而不是FreeLibrary ,我假设Plugin_FreeLibrary发生在一个地方。