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. javascript之尺寸,位置,溢出

    一.offsetWidth:元素的宽度,包括边框,内容,内边距. 二.offsetHeight:元素的高度,包括边框,内容,内边距. 三.offsetLeft:元素的X坐标(相对于最近已定位的祖先元素 ...

  2. SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据

    原文:SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Se ...

  3. icmp的报文,Destination Host Unreachable

    icmp的报文,Destination Host Unreachable的意思如下: http://www.corenetworkz.com/2009/05/destination-host-unre ...

  4. 转:Dynamic Binding Of RDLC To ReportViewer

    Introduction I was struggling to find the solution to bind rdlc dynamically to reportviewer .We had ...

  5. java转换字符串编码格式 (解码错误,重新解码)

    字符集概念:规定了某个文字对应的二进制数字存放方式(编码)和某串二进制数值代表了哪个文字(解码)的转换关系. 我们在计算机屏幕上看到的是实体化的文字,而在计算机存储介质中存放的实际是二进制的比特流. ...

  6. 了解XSS攻击

    XSS又称CSS,全称Cross SiteScript,跨站脚本攻击,是Web程序中常见的漏洞,XSS属于被动式且用于客户端的攻击方式,所以容易被忽略其危害性.其原理是攻击者向有 XSS漏洞的网站中输 ...

  7. Tomcat部署项目的几种常见方式

    以前学习的时候只知道在Eclipse或者MyEclipse中发布项目到Tomcat,最近实习时发现不同的项目还有不同的发布方式,所以特地学习了Tomcat发布项目的方式,在此记录下来. 1 直接将we ...

  8. Android 4.4 Kitkat Phone工作流程浅析(六)__InCallActivity显示更新流程

    本文来自http://blog.csdn.net/yihongyuelan 转载请务必注明出处 本文代码以MTK平台Android 4.4为分析对象,与Google原生AOSP有些许差异,请读者知悉. ...

  9. BestCoder Round #14 B 称号 Harry And Dig Machine 【TSP】

    称号:Harry And Dig Machine 哈哈  最终涨边粉色了,不easy呀.顺便写一道题解吧 题意:给一个m*n的矩阵,然后当中最多由10个有值,求总左上角把全部的值都拿上回到左上角的最小 ...

  10. 设计模式入门之职责链模式Chain Of Responsibility

    //职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. //实例:申请费用的功能,不同金额的费 ...