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

编辑 spec 文件(参考 http://www.mingw.org/wiki/HOWTO_Use_the_GCC_specs_file)
生成默认的 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

下载 http://iweb.dl.sourceforge.net/project/mingw/MinGW/Base/w32api/w32api-4.0.3/w32api-4.0.3-1-mingw32-src.tar.lzma 并解压;
修改 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

转载于:https://www.cnblogs.com/JesseFang/p/3991832.html

MinGW 使用 msvcr90.dll相关推荐

  1. 电脑提示msvcr90.dll丢失的解决方法

    在我们打开软件或者游戏的时候,电脑提示msvcr90.dll丢失怎么办呢?msvcr90.dll是电脑系统非常重要的文件,属于是动态链接库中组件.丢失会导致软件跟游戏无法正常运行打开,小编今天就把修复 ...

  2. VC 使用 MinGW编写的dll

    参考文章: ①http://www.360doc.com/content/10/0907/16/169163_51891922.shtml ②http://www.adp-gmbh.ch/win/mi ...

  3. dll.a和lib 引用MinGW生成的dll.a后出现的问题

    在安装nlopt优化库的时候遇到了一个问题,就是安装包中没有.lib文件,只有.dll.a文件,所以就各种搜,终于找到了一个解决办法,如下所示: 下面的文章转载自https://www.cnblogs ...

  4. 缺少vcomp90.dll和msvcr90.dll

    问题描述:运行MATLAB时出现缺少***.dll动态链接库 解决办法: 1.下载并安装微软VC++2013版(电脑vc++对应版本)运行库 (英文全称:Microsoft Visual C++ 20 ...

  5. 用VC和MinGW导出dll的def和lib(a)文件

    为什么80%的码农都做不了架构师?>>> 原文地址:http://zhangyafeikimi.iteye.com/blog/404580 有了dll文件需要导出def文件:  pe ...

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

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

  7. msys下产生dll的导入库

    有些时候在只有一个dll的情况下,如果需要隐式链接的话,就需要为该dll产生一个导入库.注意导入库是不能跨编译器使用的,在mingw中导入库需要以.a结尾,而vs则以.lib 以下的方法是在Msys产 ...

  8. ZZmsvcprt.lib(MSVCP90.dll) : error LNK2005:已经在libcpmtd.lib(xmutex.obj) 中定义

    FROM: http://blog.csdn.net/sptoor/article/details/6203376 很久没有写程式设计入门知识的相关文章了,这篇文章要来谈谈程式库 (Library) ...

  9. msvcprt.lib(MSVCP90.dll) : error LNK2005:已经在libcpmtd.lib(xmutex.obj) 中定义

    转载 很需要补充的知识. 可惜网络阅读一直不是强项. 目前实在有点看不进去. 先保存下来吧... 牛到连评论都是贼深奥滴! 很久没有写程式设计入门知识的相关文章了,这篇文章要来谈谈程式库 (Libra ...

最新文章

  1. C语言实现SHA-1
  2. Silverlight实用窍门系列:65.Silverlight的数据模板DataTemplate(一)使用数据模板
  3. 思科网络设备及配置详解,网工入门必备指南!
  4. 重识JavaScript 之 数据类型的相互转换
  5. Ubuntu下Eclipse中文乱码解决
  6. SQL Server将表数据从一个数据源复制到另一个数据源(未完成)
  7. 基于51单片机与wifi模块(esp8266-12f)实现对LED灯的控制
  8. 简单易懂的贝叶斯公式
  9. 偏差、误差、训练误差、测试误差
  10. 计算机编辑功能在哪,win10系统本地组策略编辑器在哪的具体步骤
  11. 2020面试题合集之吊打面试官系列(一),Android中为什么需要Handler
  12. 点云ply格式文件详解
  13. java get请求405_get方法没问题,post方法报405错误
  14. 2020-08-22
  15. 马士兵 java 学习笔记_马士兵java教程笔记1
  16. Chapter(MySQL)(基础知识)
  17. excel表格下拉选项怎么设置_excel怎么筛选?excel表格中筛选怎么用?
  18. 墨尔本大学和悉尼大学计算机专业,墨尔本大学和悉尼大学计算机专业哪个好?...
  19. SnapKit安装与使用
  20. 性能测试报告(实例)

热门文章

  1. 1327集群_MPT1327集群通讯系统
  2. HTTP中CORS跨域请求的实现(C++|Qt框架实现)
  3. Qt文件编码转换工具(三) Qt界面设计
  4. Qt + Python + OpenCV图标替换工具 之 获取颜色及生成图片(二)
  5. Qt工作笔记-undefined reference to `vtable for MyObject'及对moc文件的进一步理解
  6. C/C++基础面试-Const的全面理解(C部分)
  7. 丘成桐中学计算机科学奖,丘成桐中学科学奖
  8. 最小二乘法幂函数C语言,跪求最小二乘法幂函数C 语言程序
  9. java多线程模拟loadrunner进行压测
  10. 手机端测试时用的几个软件