MinGW 编译出来的程序总是使用 VC6 的 msvcrt.dll ,VC8,9,10有很多新的API(仅限于c runtime),想使用怎么办?
比如:boost 对 MinGW 最低要求就是 msvcrt 7.0
 

1.MinGW 系统默认情况

MinGW 根据宏 MSVCRT_VERSION 来选择 msvcr 版本,如果用户未指定则默认使用 VC7 的 API(bug, MinGW 默认链接的是 msvcrt.dll, 虽然与 msvcr70.dll 差别不是太大)
 
MinGW 4.8 (w32api-4.0.3-1) 中有如下定义,根据目标操作系统的版本来确定运行时(链接时候依然需要手动指定特定版本 msvcrt)
 
文件 /MinGW/include/_mingw.h

/*
* We need to set a default MSVCRT_VERSION which describes the MSVCRT.DLL on
* the users system. We are defaulting to XP but we recommend the user define
* this in his config.h or Makefile file based on the minimum supported version
* of OS for his program.
* ME = 600
* XP = 710
* VISTA = 800
* WIN7 = 900
* WIN8 = 1010
*/
#ifndef MSVCRT_VERSION
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
#define MSVCRT_VERSION 1010
#elif _WIN32_WINNT >= _WIN32_WINNT_WIN7
#define MSVCRT_VERSION 900
#elif _WIN32_WINNT >= _WIN32_WINNT_VISTA
#define MSVCRT_VERSION 800
#elif _WIN32_WINNT >= _WIN32_WINNT_WINXP
#define MSVCRT_VERSION 710
#elif _WIN32_WINNT >= _WIN32_WINNT_WIN2K
#define MSVCRT_VERSION 700
#elif _WIN32_WINNT >= _WIN32_WINNT_WINME
#define MSVCRT_VERSION 600
#else
#define MSVCRT_VERSION 700
#endif /* _WIN32_WINNT >= _WIN32_WINNT_WINME */
#endif /* ndef MSVCRT_VERSION */
 
MinGW 4.7 及之前是通过宏  __MSVCRT_VERSION__ 来选择 msvcr 的版本的。
 

2. MinGW 使用高版本 VC runtime

生成默认的 GCC spec 文件
gcc -dumpspecs > <mingw-root>/lib/gcc/mingw32/<gcc-version>/specs
 
修改 specs 文件中的  cpp 和 libgcc (标红部分)
 
*cpp:
-DMSVCRT_VERSION=0x0710 %{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} %{pthread:-D_REENTRANT} %{!no-pthread: } 
 
*libgcc:
%{mthreads:-lmingwthrd} -lmingw32 %{shared-libgcc:-lgcc_s} %{!shared-libgcc:-lgcc_eh} -lgcc -lmoldname71 -lmingwex -lmsvcr71
 
注意:此方法只能支持从 msvcrt.dll 改为 msvcr70.dll 或者 msvcr71.dll
 
链接更高版本的 msvcr 动态库时候,如 msvcr90.dll,会提示无法定位 _findfirst 于 msvcr90.dll 上。
 
此问题的原因在于:MinGW 在链接阶段会链接 libmingwex.a 库,而此库是以 VC6 为环境编译的,其依赖 msvcrt.dll。 所以也需要以 VC8,9,10 的环境编译多份 mingwex ——这里可以取巧仅以 VC8 为环境编译一个版本即可,因为 VC8 相比 VC71 API 改变很多,但跟后续的 VC9,10 差别不大。
 

3. 重新编译 libmingwex.a

修改 w32api-4.0.3-1.mingw32-src/Makefine.in 指定 VC 运行时的版本(这里指定 vc8 ,同时附带将操作系统版本最低要求改为xp)
ALL_CFLAGS=$(CFLAGS) $(INCLUDES) -DNTDDI_VERSION=0x05010000 -DMSVCRT_VERSION=800
 

MinGW win32api 4.0.3-1 的头文件中关于 findfirst findnext 的定义不正确,需要修改替换 wchar.h 和 io.h,点此下载

 
然后重新编译

./configure

make
 
将编译后的 ligmingex.a 拷贝至 MinGW/lib 目录,记得加个后缀,这里依赖 vc8 所以改名为 libmingex80.a 。
修改 spec 文件,将 -lmingwex 改为上面的新文件。
*libgcc:
%{mthreads:-lmingwthrd} -lmingw32 %{shared-libgcc:-lgcc_s} %{!shared-libgcc:-lgcc_eh} -lgcc -lmoldname80 -lmingwex80 -lmsvcr80
 
然后随便编译一个文件,运行程序则会报如下问题,找不到 msvcr90.dll 
 
强制拷贝一个 msvcr90.dll 到程序目录,但运行时候则报 R6034 的问题,见下图
对此问题,在生成的目标 exe 目录下手动创建一个 manifest 文件即可解决。
文件名: 程序名.后缀.manifest
内容(version 需要根据你系统的 msvcr 版本修改):
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level='asInvoker' uiAccess='false' /> <!-- VC2008 新增,程序是否需要以管理员运行 -->
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.VC90.CRT' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </dependency>
</assembly>
 
 
备注:网上有说想链接高版本 msvcr,只需编译时候 不链接任何 MinGW 的标准库,只链接 msvcr 和 gcc (细节见http://stackoverflow.com/questions/3402252/how-to-link-against-msvcr90-dll-with-mingw-gcc),但实际结果如下:
$ gcc a.c -nostdlib -lmsvcr80 -lgcc
d:/msys/mingw/bin/../lib/gcc/mingw32/4.8.1/libgcc.a(__main.o):(.text+0x5a): undefined reference to `atexit'
collect2.exe: error: ld returned 1 exit status

4. 嵌入manifest

1. 
发布程序时为了简单,可以用 mt.exe (VC中的工具) 嵌入manifest
对于exe
   mt.exe –manifest MyApp.exe.manifest -outputresource:MyApp.exe;1
对于dll
   mt.exe –manifest MyLibrary.dll.manifest -outputresource:MyLibrary.dll;2
 
 
 
2.
每次编译都得手动拷贝一个 manifest,确实非常烦人,这里使用更方便的方法。将manifest文件编译为资源,然后让MinGW链接
创建文件 msvcr.rc
 
#include "winuser.h"
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST msvcrt.manifest
创建 msvcrt.manifest ,内容同前面的manifest即可
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level='asInvoker' uiAccess='false' />
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.VC90.CRT' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
</dependentAssembly>
</dependency>
</assembly>
使用 MinGW 的 windres 将前面的 manifest 编译为资源
windres --input msvcr.rc --output msvcr90_manifest.o
 
将生成的 msvcr90_manifest.o 放到 MinGW 的 lib 目录,
修改 MinGW 的 spec 文件,startfile 部分增加
 
*startfile:
%{shared|mdll:dllcrt2%O%s} %{!shared:%{!mdll:crt2%O%s}} %{pg:gcrt2%O%s} crtbegin.o%s msvcr90_manifest.o%s

MinGW 使用 msvcr90.dll的更多相关文章

  1. 让VC编译出来的程序不依赖于msvcr80.dll/msvcr90.dll/msvcr100.dll等文件

    ---转载:http://hi.baidu.com/liu_haitao/item/e2157ac3a3c32a0bc610b253 让VC编译出来的程序不依赖于msvcr80.dll/msvcr90 ...

  2. 转载: 找不到MSVCR90.dll、Debug vs Release及cppLapack相关

    今天调试程序时出现了,找不到MSCVR90.dll的错误,最好查找到了解决办法,原文链接如下:   http://hi.baidu.com/wpzhao/blog/item/72dc08f77ce9b ...

  3. 在 Windows 下用 TDM-GCC(MinGW)开发 DLL 涉及到数据同步锁及 DLL 初始化终止化函数的问题

    在 Windows 下用 TDM-GCC(MinGW)开发 DLL 如果要用到数据同步锁,理论上可以采用 Windows API 提供的临界区实现(需要用到的函数有 InitializeCritica ...

  4. 引用MinGW生成的.dll.a后出现的问题

    以前很少调用MinGW的运行时库,现在用到一个项目,用到了glib和gettext等. 遇到了一个问题,折腾了一个下午. gettext的运行时库之一是intl,MinGW只提供了.dll.a,于是参 ...

  5. VC 调用 MinGW 生成的dll good

    首先,如果dll 中导出了C++的类,那么就不要折腾了.不同的编译器编译出来的C++代码是不保证通用的.如果dll中只是一些C 函数,那么是可以互相调用的. MinGW 生成dll时即使生成了 .a  ...

  6. 文件转换dll mingw

    MinGW:c -> o           gcc -c a.cc -> exe         gcc a.c libs.o -o a.exe (从主程序a.c,附加libs,生成a. ...

  7. MSVC vs. MinGW 之dll玩转攻略手记【转

    一份粗糙的研究记录,有待补完和整理. MinGW:c -> o           gcc -c a.cc -> exe         gcc a.c libs.o -o a.exe ( ...

  8. dll = MinGW gcc 生成动态链接库 dll 的一些问题汇总

    MinGW gcc 生成动态链接库 dll 的一些问题汇总 https://blog.csdn.net/liyuanbhu/article/details/42612365 网络上关于用 MinGW  ...

  9. MinGW gcc 生成动态链接库 dll 的一些问题汇总(由浅入深,很详细)

    网络上关于用 MinGW gcc 生成动态链接库的文章很多.介绍的方法也都略有不同.这次我在一个项目上刚好需要用到,所以就花了点时间将网上介绍的各种方法都实验了一遍.另外,还根据自己的理解试验了些网上 ...

随机推荐

  1. Unattended Setup Software Components (无人值守安装软件组件)

    原文 http://social.technet.microsoft.com/Forums/windows/en-US/d4ad85b4-8342-4401-83ed-45cefa814ec5/una ...

  2. html模块一些方法

    <pre name="code" class="python"> find_by_tag_name: @elements = $h->find ...

  3. OpenCV在ARM上的移植

    OpenCV在ARM上的移植 与X86 Linux类似,请参考:Linux 下编译安装OpenCV 本文在此基础上进行进一步操作. 网络上很多移植编译的方法比较老,多数针对OpenCV 1.0,而且方 ...

  4. VBA:Google翻译(含tk算法)

    完整的tk算法: //源自http://translate.google.cn/ TKK=eval('((function(){var a\x3d618632403;var b\x3d14854840 ...

  5. html 表格中文字的背景色

  6. 本人对于JavaScript的一些总结

    类型.值和变量 1.原始类型   数字.字符串和布尔   null空  undefined未定义 2.对象类型 3.类  Array  Function Date RegExp  Error 4.js ...

  7. Sublime Text 添加到右键菜单 带菜单图标

    1.打开 regedit 2.找到节点 HKEY_CLASSSES_ROOT -> * -> Shell 3.右键选择新建“ 项 ” 这个项的名字将作为右键菜单的菜单名称,我用的“ Sub ...

  8. W3C-XML

    XML XML Extensible Markup Language,可扩展标记语言 1 XML和HTML的区别 XML主要用来传输数据 HTML主要用来呈现数据内容 2 XML的主要用途 传输数据 ...

  9. JDBC插入百万数据,不到5秒!

    java自带的批量操作,就可以很好的支持大量数据的处理.相比c#,简单很多.c#要使用oracle提供的ODP.NET,效率才很高,但是代码却很复杂.总之,在这方面,c#没得比.当然,这里的表是没加索 ...

  10. 在任务计划程序用Bat命令执行exe程序

    @echo off :open choice /c:123 /m "1:创建,2:终止,3:删除" if errorlevel 3 goto delete if errorleve ...