gpt4 book ai didi

c - Visual C 链接器在 32 位和 64 位上的行为不同

转载 作者:太空宇宙 更新时间:2023-11-04 03:27:06 25 4
gpt4 key购买 nike

看看下面的示例代码:

__declspec(dllexport) FreeLibrary(void)
{
}

我使用以下小脚本将其构建为 DLL:

cl /EHsc /MT /c test.c /Fotest.o
link /dll /out:test.dll test.o

这在为 32 位架构编译时工作正常。但是,在针对 64 位架构进行编译时,未构建 DLL 并且出现以下错误:

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

这是为什么呢?为什么它在 32 位上工作但在 64 位上不工作? FreeLibrary 符号不应该也在 32 位 kernel32.dll 中定义吗?但为什么 32 位链接器不提示并构建 DLL 就好了?

这让我很困惑......

最佳答案

经过编辑以更正 IInspectable 发现的错误并为清楚起见

32 位

默认的调用约定是__cdecl ,这会导致符号名称前面带有下划线:_FreeLibrary

>dumpbin /symbols test.o | find "FreeLibrary"
008 00000000 SECT3 notype () External | _FreeLibrary

kernel32.dll 中的FreeLibrary 是用WINAPI 声明的。在 32 位中,WINAPI 扩展为 __stdcall,因此 kernel32 的函数被命名为 _FreeLibrary@4

>dumpbin /exports kernel32.lib | find "FreeLibrary"
_FreeLibrary@4
_FreeLibraryAndExitThread@8
_FreeLibraryWhenCallbackReturns@8

因为 _FreeLibrary 不匹配 _FreeLibrary@4,所以没有冲突。

64 位

默认调用约定是 four-register fastcall不修饰普通 C 函数名称的方案。因此 test.o 定义了一个名为 FreeLibrary 的符号:

>dumpbin /symbols test.o | find "FreeLibrary"
008 00000000 SECT3 notype () External | FreeLibrary

此外,WINAPI 宏扩展为空,因此 kernel32.dll 使用与您的插件代码相同的默认调用约定。因此它得到了相同的、朴素的符号:

>dumpbin /exports kernel32.lib | find "FreeLibrary"
FreeLibrary
FreeLibraryAndExitThread
FreeLibraryWhenCallbackReturns

这会为您提供两个 FreeLibrary 符号并导致链接器错误。

关于c - Visual C 链接器在 32 位和 64 位上的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40289429/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com