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. USB Mass Storage学习笔记-STM32+FLASH实现U盘

    一.内容概述  采用STM32内部自带USB控制器外加大页NAND FLASH K9F1G08U0A实现一个128M的U盘. 1.STM32的USB控制器 STM32F103的MCU自带USB从控制器 ...

  2. List<T>类

    List<T>类是ArrayList的泛型等效版本,两者功能相似.它实现了6个接口,实际上市对应的3对. 1.IEnumerable<T>和IEnumerable 2.ICol ...

  3. toolkit,phonetextbox中实现用户按回车键会换行

    今天,了解到一个需求,要在输入框中实现:用户按回车键后换行 输入框是toolkit中的phonetextbox 1.首先google了一下,了解到有MultiLine这个属性,但是找寻了一番之后,居然 ...

  4. 改变UITableViewCell按下去的颜色

    UIView *bgColorView = [[UIView alloc] init]; [bgColorView setBackgroundColor:[UIColor redColor]]; [c ...

  5. Android - 使用Intent来启动Activity

    本文地址: http://blog.csdn.net/caroline_wendy/article/details/21455141 Intent 的用途是 绑定 应用程序组件, 并在应用程序之间进行 ...

  6. Android系统的开机画面显示过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7691321 好几个月都没有更新过博客了,从今天 ...

  7. react-native 环境配置及hello world

    一.前言 最近手头的工作繁多,有研究性的项目和系统研发,正好遇到同事离职,接手了框架的UI组件,不仅需要维护和填坑,还需要开发新的功能组件.因为身在H5-Hybird的框架部门,最近团队开始尝试使用R ...

  8. [生成树][Uva1395][Slim Span]

    代码: #include <set> #include <queue> #include <cmath> #include <cstdio> #incl ...

  9. pureftpd的搭建

    1,安装purefptd软件 ftp(file transfer protocol) 文件传输协议 cd  /usr/local/src  wget https://download.pureftpd ...

  10. JAVA HashMap与HashTable 区别

    HashTable和HashMap区别 第一,继承不同. public class Hashtable extends Dictionary implements Mappublic class Ha ...