【问题标题】:How do I create a Win32 DLL without MSVCR90D.dll?如何在没有 MSVCR90D.dll 的情况下创建 Win32 DLL?
【发布时间】:2009-05-12 20:15:55
【问题描述】:

我正在尝试使用一个简单的函数重新创建现有的 C Win32 DLL。我已经设法使用 VS C++ 2008 Express 做到了这一点,并且我的新 DLL 可以在我的 Vista 开发机器和客户端的 XP 机器上运行。但是,它不适用于其他网站。我检查了依赖项,我的 DLL 需要 MSVCR90D.dll 和 KERNEL32.dll,而原始 DLL 只需要 KERNEL32.dll。

什么是 MSVCR90D.dll,如何创建一个没有这种依赖关系的简单 Win32 DLL?

【问题讨论】:

    标签: c winapi compiler-construction


    【解决方案1】:

    MSVCR90D.dll 末尾的 D 表示您在调试模式下编译了 .exe。您应该只在发布模式下分发您的应用程序。

    您可以通过让他们安装 Microsoft Visual C++ 2008 Redistributable Package x86x64 来确保他们拥有所需的一切。否则,您可以通过在计算机上找到它们来简单地复制他们需要的文件(首先检查 %systemroot%\system32)

    请参阅this MSDN link

    【讨论】:

    • 对于建议从计算机的 system32 文件夹中抓取运行时 DLL 的答案,我无法给出 +1。不是一个好主意。问题是需要在目标机器上正确处理并排组装机制,简单的文件复制不太可能正确。
    • @RBeteig:“并行组装机制”是什么意思?将 dll 放在应用程序所需的文件夹中有什么问题?我不建议复制到他们的 system32 文件夹。
    【解决方案2】:

    名称中的“D”表示调试。这是 Visual Studio 的调试版本的明确指示。使用 Release 版本,一切都会好起来的。

    如果目标系统还没有 C 运行时,一般应该使用官方安装程序来安装。您可能想了解的一些运行时版本如下:

    您还可以开发一个完整的安装包,其中包括您的应用程序所需的可再发行 DLL(但从不调试 DLL)并处理将并行 (SxS) 程序集安装到系统程序集中使用称为合并模块的技术正确缓存。如果您已完整安装 Visual Studio(不是免费的 VS Express 版本),则此方法更容易,但生成的安装包仍然可能无法很好地处理旧平台(例如 Win 2K 或 9x)上运行时的安装。

    MSDN 文章Redistributing Visual C++ Files 描述了规则是什么,以及如何尽可能轻松地遵守它们。它为了解与部署相关的许多问题提供了一个起点。

    如果您要替换其功能的原始 DLL 没有对 MSVCR90.DLL 的引用,则它必须已静态链接到运行时。您可能应该检查将调用您的 DLL 的预期应用程序的假设。在单个进程中混合 C 运行时库并不总是那么容易。如果宿主应用程序已经在使用 MSVCR90.DLL,那么您也应该这样做。但是,这是一个比手头特定问题的答案更大的问题,因此我鼓励您研究它并根据需要提出新问题。

    另一种避免安装后期运行时 DLL 的方法是链接到 MSVCRT.DLL,它作为系统组件与现代版本的 Windows 一起分发。这是 Visual C 6.0 附带的运行时,针对关键问题进行了轻微更新,并保持最新以匹配操作系统。它根本不适用于 64 位版本,而且很难欺骗 Visual Studio 使用它来代替较新的运行时。

    【讨论】:

      【解决方案3】:

      与 C 运行时库的静态版本链接。该设置位于项目属性中的“代码生成”下。这样您就完全不用担心 MSVCR* DLL。

      【讨论】:

      • 如果您正在为应用程序编写插件,您总是需要担心,这样您就不会以不兼容的 malloc/free 实现而告终。在任何情况下,D 都意味着 Debug,并且有很多理由从不部署 Debug 版本。
      • @RBerteig:一般来说,你对 malloc/free 等的看法是正确的,但在这种情况下,ProfK 正在重新创建一个不依赖于 CRT DLL 的现有 DLL。他不会通过让他的新 DLL 以同样的方式工作来引入问题。
      • 抱歉,在重读时,我看起来可能有点苛刻。当真正的问题是 Debug 构建时,我经常看到只链接静态的建议,而这些天它是我的一个小烦恼。当托管应用程序要求依赖项确实位于相同的运行时时,它实际上会造成伤害。如果我们假设旧的 DLL 确实按照构建的方式工作,那么静态链接可能确实是正确的答案。
      • 与静态运行时链接并不总是可行的。例如。当使用 /clr
      • 静态链接调试运行时库,然后将该可执行文件分发到未安装相关编译器的计算机,这违反了编译器的许可条款。
      【解决方案4】:

      检查您客户的机器是否在他的系统上安装了 2008 运行时。如果没有,您可以将其安装在他/她的系统上,或者使用您的应用程序静态编译运行时。

      【讨论】:

        【解决方案5】:

        您可能想要做的是构建 DLL 的发布版本,对其进行测试,然后分发它,而不是现在分发的调试版本。

        但是,可以创建依赖于 MSVCR90.DLL(该 DLL 的非调试版本)的调试 DLL。为此(VS 2008 SP1,其他 VS 的说明类似):

        1. 转到项目属性(右键单击解决方案资源管理器窗格中的项目,从菜单中选择属性)。
        2. 进入配置属性\C/C++\代码生成。
        3. 在运行时库下,您可能选择了“多线程调试 DLL”。将此更改为“多线程 DLL”。

        您必须重新编译所有内容,但您现在应该链接非调试 VS DLL。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-01-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-08
          • 1970-01-01
          相关资源
          最近更新 更多