【问题标题】:How to include all dll's in exe?如何在exe中包含所有dll?
【发布时间】:2014-05-24 12:12:51
【问题描述】:

我有一个 Visual Studio 12 项目;用 C++ 编写的源代码;这是一个 OpenCV 项目。我想将我编译的程序提供给其他人,但是在其他 PC 上,我收到一条关于缺少一些 dll 的错误消息。我的程序使用了许多 OpenCV(也许,不仅仅是)dll。 我该如何解决这个问题? 也许在 VS 12 中可以选择将所有 dll 包含在 .exe 中? 这是一个非常相似的问题,没有正确的答案: include dlls in visual studio c++ 2008

【问题讨论】:

  • @LuchianGrigore:您不能静态链接 DLL。 DLL 是围绕动态链接构建的。是的,静态链接将是可行的方法,但您需要一个静态库。
  • @datenwolf 是的,我的意思是静态链接:)
  • @Joe 那里提供的答案(在该页面上)对我没有帮助。我已经完成了这些步骤(由 Zaw Lin 提供)。

标签: c++ opencv visual-studio-2012 dll exe


【解决方案1】:

DLL 本身不能“静态链接”到可执行文件中;这完全违背了他们的目的(好吧,实际上你可以使用一些非常奇怪的巫毒技巧来实际做到这一点,但这既不推荐也不应该尝试,如果你不得不问这个问题)。

简单的解决方案是识别程序所需的所有 DLL(只需在调试器中启动程序就会生成一个日志文件,列出所有这些)并将这些 DLL 复制到与 EXE 所在的目录相同的目录中;碰巧,EXE 文件所在的目录也是系统在进入默认配置中的标准系统目录之前查找 DLL 的第一个目录。将其打包并以这种方式分发。

【讨论】:

  • 我知道这是一篇很老的帖子,但我对实现这项工作的“奇怪的巫术技巧”非常感兴趣。你能详细说明一下吗?
  • @MooseBoys:给出一个粗略的总结。所涉及的步骤是使用类似于 objcopy 的工具(也许您甚至可以为此使用 objcopy)或 objdump 将 DLL/共享对象“分离”到普通对象文件中。然而,DLL/共享对象有入口点DllMain/_init/_fini,它们在特殊时间被调用。还有几个用于符号位置翻译的特殊部分。 Windows DLL 允许进程间共享内存部分。等等等等。最终,您会将所有内容拆分为对象并重新链接为静态库。
  • @MooseBoys:另一种方法是简单地将整个 DLL/共享对象作为二进制 blob 嵌入可执行文件中。在程序启动时,可执行文件的一部分可以被重新映射为虚拟文件/文件视图并传递给动态链接器。
  • @MooseBoys:还有一种方法是在可执行文件中实现自定义动态链接器,并让它直接与嵌入式 DLL/共享对象的二进制 blob 一起工作。 – 除了 delink/relink 方式之外,其他两种方法都非常可怕(主要是出于安全原因)。
  • @schlebe:最初的问题是,如果首先没有运行时环境解释器,如何“嵌入”一个 DLL(或静态链接它)。这是一个完全不同的问题范围。并且与其他操作系统进行比较正在移动目标,因为 OP 会询问特定的操作系统,而其他系统的“营销”在这里没有帮助。
【解决方案2】:

更复杂的解决方案是,从 src 构建静态 opencv 库,然后将您的程序与这些库链接,产生 1 个不使用任何 dll 的大型二进制 exe 块(除了 ffmpeg,不确定那个)。

要构建静态库,您需要使用以下命令运行 cmake:BUILD_SHARED_LIBS=OFF

但在此之前深吸一口气。链接您的程序将更加困难,因为现在您必须手动链接所有 zlib、libpng 和任何依赖项(之前可以方便地链接到您的 dll 中)

同样,最简单的解决方案是使用您的程序部署所有 opencv dll。

【讨论】:

    【解决方案3】:

    您可以使用Windows Dependency Walker 来确定您的程序需要运行哪些 DLL。

    实际上,这只是告诉您程序需要哪些 DLL 才能成功启动。如果您动态加载 DLL(通过 LoadLibrary),那么您就得靠自己了。

    【讨论】:

      【解决方案4】:

      如果您选择接受的解决方案(将 DLL 与 EXE 文件一起打包),并且您不想费心寻找要使用的 DLL,那么您可以复制所有 OpenCV DLL。它们不是那么大(OpenCV 2.43 上为 65 MB)。它们位于...\opencvXXX\build\x64\vc10\bin\

      XXX 是 OpenCV 版本。您可以使用 x64x86,具体取决于您的平台(32 位或 64 位)。并且vc 的版本在您的系统上可能不同(vc9vc10 等...)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-15
        • 1970-01-01
        相关资源
        最近更新 更多