【问题标题】:DLL linker issueDLL 链接器问题
【发布时间】:2010-09-09 22:39:09
【问题描述】:

我正在编译 DLL 两次(一次用于 x86,一次用于 x64)并且我已将 /ENTRY 设置为“DllMain”。我正在使用 /MT 运行时库选项静态链接到运行时库。在进行 x86 构建时,这一切都可以正常工作,但 x64 构建失败:

error LNK2019: unresolved external symbol main referenced in function __tmainCRTStartup
{project directory}\LIBCMT.lib(crt0.obj)

为什么这适用于 x86 构建而不是 x64 构建?我在这里有什么遗漏吗?

【问题讨论】:

  • 你为什么使用 /ENTRY? IIRC,如果您使用的是标准 DllMain() 函数,则运行时会在没有任何额外帮助的情况下调用它。
  • 如果我在 x86 DLL 中指定 /ENTRY,则 DLL 的最终大小为 5kb,如果我不设置 /ENTRY,则最终大小超过 50kb。
  • 通常 real 入口点由 CRT 提供的“假” DllMain 获取,以初始化其内部数据结构(如此处所述:stackoverflow.com/questions/2674736/loading-a-dll-from-a-dll/…),所以你'重新绕过它。尺寸减小可能是由于删除了 CRT 初始化代码。您的 dll 正在使用未初始化的 CRT,这非常糟糕。
  • @Matteo:非常有趣,我不知道。您应该将此作为答案发布,以便我接受。 :)
  • 好的,我之前没有发布它作为答案,因为它不完全是您问题的答案,而是运行时可能出现的另一个问题。 :)

标签: windows dll linker


【解决方案1】:

不是直接的答案,但可能是严格相关的:正如评论中所说,您应该避免以这种方式更改入口点:通常真正的入口点由 CRT 提供的“假” DllMain 获取,以初始化其内部数据结构(如here 解释的那样),所以你绕过它。尺寸减小可能是由于删除了 CRT 初始化代码。

您的 dll 正在使用未初始化的 CRT,这非常糟糕。您应该保留默认入口点,顺便说一句,它应该可以解决您的问题。

顺便说一句,请注意实际上您可以在没有 CRT 的情况下创建一个 dll(它会变得非常小),但您根本不应该使用 CRT,甚至没有链接它(/NODEFAULTLIB 开关)。这意味着您可以只使用显式链接的库(例如 Windows API),但我怀疑您会失去一些 C++ 功能(我认为至少有例外和 RTTI)。

【讨论】:

    【解决方案2】:

    这可能是一个愚蠢的问题,但你确定你在 x64 情况下作为 DLL 链接(即指定 /DLL 开关) - 因为投诉是关于 main,我想知道它是否正在尝试链接为可执行文件?

    【讨论】:

    • 在“常规”选项卡上,我将配置类型设置为“动态库 (.dll)”。这是你的意思吗?
    • 听起来不错。您应该通过项目设置的链接器/命令行页面比较两个目标的链接器命令行。
    • 我比较了命令行,唯一不同的部分(除了输出文件夹)是 /MACHINE 选项。
    • @Jon: ...并确保检查 x86 和 x64 目标的调试和发布设置。在设置诸如配置类型之类的内容时,该项目属性对话框可以很容易地省略这四个位置之一。
    • 我什至没有 Debug 设置,只有 Release。 :) 一个有趣的注释,如果我使用 /MD 它工作正常,但使用 /MT 不会链接。我确实需要静态链接它以避免分发 C++ 运行时 DLL。
    猜你喜欢
    • 2013-10-10
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 2011-05-08
    • 2020-02-19
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多