强制 x64 DLL 中的名称修改 [英] Forcing name mangling in x64 DLL

查看:26
本文介绍了强制 x64 DLL 中的名称修改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将 32 位应用程序移植到 64 位.该应用程序支持 DLL 插件.不幸的是,每个插件需要具有的强制性功能之一称为 FreeLibrary,这当然与同名的 kernel32 API 冲突.我的插件 API 使用 FreeLibrary 名称的原因是该应用程序源自不同的平台,其中 FreeLibrary 不会与任何操作系统 API 发生冲突.

I am porting a 32-bit application to 64-bit. The application supports plugins which are DLLs. Unfortunately, one of the mandatory functions each plugin needs to have is called FreeLibrary which of course conflicts with the kernel32 API of the same name. The reason why my plugin API uses the FreeLibrary name is that the application originated on a different platform where FreeLibrary doesn't clash with any OS APIs.

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

However, even on 32-bit Windows using FreeLibrary is not a problem because 32-bit DLLs use name mangling, i.e. the function is stored as _FreeLibrary and hence doesn't clash with the kernel32 API.

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

On 64-bit, though, I have a problem now because 64-bit doesn't seem to use name mangling. On 64-bit the compiler creates a symbol named FreeLibrary and this of course clashes with the kernel32 API of the same name and refuses to link, leading to the following error:

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?

Thus, I'm wondering whether there is any way to force x64 DLLs to use name mangling as on 32-bit so that my DLL can export a symbol named FreeLibrary without any clashes with kernel32?

或者是否有其他解决方案可以解决此问题?

Or is there any other solution to work around this problem?

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

The only solution I see is to rename FreeLibrary to something that doesn't clash with OS APIs for the x64 versions of my application but of course I'd like to avoid this because it reduces the consistency of my application's plugin API. If possible, I'd like to keep the FreeLibrary name across all platforms and architectures.

有什么想法吗?我想如果在 32 位上可以在 DLL 中使用像 FreeLibrary 这样的保留名称,那么应该有一种方法可以在 64 位上做到这一点,不是吗?但我不明白...

Any ideas? I guess if it was possible on 32-bit to use reserved names like FreeLibrary in a DLL then there should be a way to do it on 64-bit as well, shouldn't there? But I don't see how...

推荐答案

我不会试图说服编译器修改函数的名称.那种方式就是疯狂.

I would not try to convince the compiler to mangle the names of the functions. That way lies madness.

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

To clarify, your only issue is the duplicate symbols when linking plugin DLLs. The application itself shouldn't care what the functions are named, because it's going to call the plugin entry points through function pointers received via GetProcAddress.

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

Assuming, the plugins don't ever need to call Windows APIs implemented in kernel32.dll, you could try omitting kernel32.dll from the linker command. (See the /NODEFAULTLIB option.) If kernel32.dll isn't part of the link, there should be no collision.

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

But that won't work because /MT in the command line implies you depend on the C run-time library, which, in turn, depends on some kernel32.dll APIs. (Also, are you sure you want to link the plugins against the static run-time library and not the DLL version?)

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

So the remaining option is to change the name of the function. This should be trivial, since you're porting anyway. You could even use the preprocessor to hack the name when compiling the plugins so that you don't need to change their source code:

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

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

And then change the GetProcAddress call in the application to look for Plugin_FreeLibrary instead of FreeLibrary, which I assume happens in just one place.

这篇关于强制 x64 DLL 中的名称修改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆