【问题标题】:Missing msvcr100.dll error while running an executable built with MinGW运行使用 MinGW 构建的可执行文件时缺少 msvcr100.dll 错误
【发布时间】:2011-08-24 16:11:57
【问题描述】:

我正在成功编译(使用 MinGW)并在我的 Win7-64 位系统上运行由多个文件组成的 C++ 程序(通过 JNI 调用 Java 类)。编译和运行由 2 个批处理文件完成。我前段时间安装了 Visual Studio C++ 2010,但从那以后就没有使用过。

我现在正尝试将此程序部署到另一台运行 WinXP-32bit 的计算机上,但我遇到了“缺少 msvcr100.dll”错误。我安装了最新的 MinGW 和 JDK,我使用相同的批处理文件编译了我的程序,但是当我运行它时,我得到了错误。建筑物的任何部分都没有使用 Visual Studio(我不希望它使用它),所以我觉得奇怪的是我收到这条关于 MSVC++ dll 的消息。

编译.bat

rem Set the include paths for the JNI header files("include" and "include\win32" inside the jdk (32-bit) directory).
set JDK_INCLUDE="C:\Program Files\Java\jdk1.7.0\include"
set JDK_INCLUDE_WIN32="C:\Program Files\Java\jdk1.7.0\include\win32"

set PATH=%PATH%;C:\MinGW\bin

rem Build an import library for the jvm.dll from the .\lib\jvm.def file (see http://www.inonit.com/cygwin/jni/invocationApi/archive.html)
dlltool --input-def .\lib\jvm.def --kill-at --dllname jvm.dll --output-lib .\lib\libjvm.dll.a

rem Set the import library directory.
set JVM_IMPORT_DLL=".\lib"

rem Compile all files (including the IngToolTest.cpp) and create an executable file .\bin\COFORM_JNI.exe
g++ -I%JDK_INCLUDE% -I%JDK_INCLUDE_WIN32% .\src\DataTypes\file1.cpp .\src\IngestionTool\file2.cpp ... .\src\file25.cpp Test.cpp -L%JVM_IMPORT_DLL% -ljvm -o .\bin\executable.exe

pause

运行.bat

Rem Set the environment parameter to the path where the properties file resides.
set CONFIG_DIR=..

Rem Set the environment parameter to the actual IP of your VM machine.
set VM_URL=139.191.173.43

Rem Set the location of the jvm.dll (32-bit)
set PATH=%PATH%;C:\Program Files\Java\jdk1.7.0\jre\bin\client

move *.rdf RDFS

.\bin\executable.exe

pause

是否有可能是我的外部包含之一导致了这种情况?他们在这里:

#include <stdio.h>
#include <cstdlib>
#include <iostream>
#include <jni.h>
#include <vector>
#include <string.h>
#include <fstream>
using namespace std;

如果能帮助我克服这个错误,我将不胜感激。

K

【问题讨论】:

    标签: c++ java-native-interface mingw


    【解决方案1】:

    虽然 MinGW 是 GCC 的一个发行版,但为了允许它在 Windows 上本地运行而无需像 Cygwin 这样的 Linux 仿真层,它不使用 GNU C 库。相反,它使用 Microsoft 的 C 运行时。我有一段时间没有使用 MinGW,当时它使用的是 VC++ 6.0 中的 MSVCRT.DLL,它在 Windows 安装中或多或少普遍存在,因为它自 Win95 后期版本以来就随安装一起提供。

    如果您安装的 Windows 没有随它一起分发并且您没有安装任何与它一起分发的应用程序,那么您安装的 Windows 很可能没有更高版本的运行时。可能你只有64位的DLL,需要安装32位的DLL。

    简单的解决方案是安装 Microsoft 的 VC++ 可再分发包。

    Microsoft Visual C++ 2010 Redistributable Package (x64)

    Microsoft Visual C++ 2010 Redistributable Package (x86)


    补充说明:根据http://mingw-w64.sourceforge.net/http://www.mingw.org,MinGW仍然依赖于MSVCRT.DLL,所以我想知道你做了什么或者你从哪里获得了使它依赖的发行版MSVCRT100.DLL?也许是一些实验性的构建?

    【讨论】:

    • 重要提示似乎每个人都知道:msvcrt.dll != VC 6.0。它随着每个主要的操作系统更新(包括服务包)而更新,与 Linux 上的 glibc 非常相似。还有一个重要的细节:很多 C 标准库在 MinGW(-w64) 中重新实现,而在 MinGW-w64 的情况下,实现速度非常快。
    • 我使用 WinXP-32bit 将我的程序部署到另一台计算机上,并且使用相同的 MinGW 编译器和 JDK 1.6(而不是第一台计算机使用的 1.7)一切正常。我想第一台计算机出现了严重错误。我知道在安装可再发行包后我的问题会得到解决(他们确实做到了),但我仍然无法弄清楚为什么需要这个 dll。无论如何,谢谢伙计们。顺便说一句,MSVCRT.DLL 存在
    • @rubenvb:我不确定是否需要注意,但是就像任何系统 DLL 一样,它会随着 Windows 版本和 Windows 更新的更新而更新。尽管如此,它最初是随 VC++6 而不是随操作系统一起提供的。 Windows 95 的早期版本不包含它。
    • Clifford:Windows 95 != 我们在当今时代使用的 Windows。您的陈述误导了不知情的用户对 MinGW 编译器生成的代码的状态和质量。
    • @rubenvb:啊,我明白你的意思了;我无意暗示 MSVCRT.DLL 是旧的或低劣的,只是因为它长期包含在 Windows 安装中而无处不在。但是你的建议是假设如果它来自Windows 95那么它一定质量很差,但是标准C库是一个非常简单的东西并且即使在那时也是非常成熟的技术,所以即使它是同一个旧的C库,那也会在任何情况下都不会损害它。我敢说,这些年来几乎没有任何变化。
    【解决方案2】:

    DLL 包含已编译程序的运行时。它必须安装在另一台机器上才能运行程序。

    标准程序发行版有一个安装包可以为您执行此操作,或者您可以手动安装。

    请参阅此处了解下载说明

    http://www.microsoft.com/download/en/details.aspx?id=5555

    【讨论】:

    • 我为什么需要这个?我没有在整个项目中使用 MSVC++。没有dll我不能运行它吗?
    • MinGW 在 Windows 上使用本机 C 和 C++ 运行时,其中 MSVCR100 是最新版本 (10.0)。您可能会将其配置为使用 XP 上的旧版本之一(但我不知道具体如何)。
    【解决方案3】:

    MinGW 仅模拟 Linux 操作系统调用。让我解释一下..

    当您创建在某个操作系统上运行的二进制文件时,该二进制文件需要知道如何与底层操作系统进行交互。这对于诸如内存分配之类的事情很重要。二进制文件本身并不“知道”如何分配 RAM,而是要求主机操作系统给它一些 RAM。它通过调用驻留在操作系统内部预定“地址”的分配函数来做到这一点。

    应用程序如何知道分配方法存在于哪个“地址”?

    当您编译二进制文件时,您将其绑定到一个“C 运行时库 (CRT)”。这个库包含二进制文件需要的所有操作系统交互的映射。例如,当您链接 CRT 时,二进制文件现在知道在哪里可以找到操作系统公开的内存分配函数。

    MinGW,插入一个仿真层,使应用程序认为它链接到 Linux CRT,但实际上,仿真层只是将调用重定向到 Microsoft CRT。

    Windows,有许多不同的 CRT 可用。在所有发行版中,您都可以在 %PATH% 的某个位置找到文件 msvcrt.dll。此文件提供二进制文件在操作系统中运行所需的所有支持。

    安装 Visual Studio 后,您将获得 CRT 的更新版本:

    1. 在 VS 2005 中:msvcrt80.dll
    2. 在 VS 2008 中:msvcrt90.dll
    3. 在 VC 2010 中:msvcrt100.dll

    显然,通过安装 Visual Studio,您已经使 MinGW 的仿真层链接到 msvcrt100.dll,而不是分布在所有 Windows 机器上的 msvcrt.dll。我不知道为什么会这样,但这IS正在发生什么。

    编辑

    命令:

    dlltool --input-def .\lib\jvm.def --kill-at --dllname jvm.dll --output-lib .\lib\libjvm.dll.a
    

    生成链接到jvm.dll 的文件可能会创建msvcrt100.dll 依赖项。也就是说,jvm.dll 可能与最新的 CRT 动态链接,并且因为您需要 jvm.dll,所以您间接需要 msvcrt100.dll

    在“C:\Program Files\Java\jdk1.7.0\bin”中有没有找到dll?

    【讨论】:

    • 它根本不模拟 Linux 调用;这就是 Cygwin 所做的。 MinGW 包括一些兼容性标头,其中在 MSVCRT 中有精确或接近等价物,但没有尝试进行仿真。 MinGW 应用程序直接访问 MSVCRT。这就是为什么例如 fork() 不可用的原因; Windows 本身不支持该进程模型。工具链本身确实使用 DLL 来提供足够的支持以允许 GNU 工具链代码本身运行,但使用它构建的应用程序不依赖于此。
    • 这个答案在与问题相关的每一点上都是错误的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多