Visual C++ 编译器选项 /MD、/ML、/MT、/LD

前段时间编译一个引用自己写的静态库的程序时老是出现链接时的多个重定义的错误,而自己的代码明明没有重定义这些东西,譬如:
LIBCMT.lib(_file.obj) : error LNK2005: ___initstdio already defined in libc.lib(_file.obj)
LIBCMT.lib(_file.obj) : error LNK2005: ___endstdio already defined in libc.lib(_file.obj)
LIBCMT.lib(_file.obj) : error LNK2005: __cflush already defined in libc.lib(_file.obj)
LIBCMT.lib(_file.obj) : error LNK2005: __iob already defined in libc.lib(_file.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __alloc_osfhnd already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __set_osfhnd already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __free_osfhnd already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __get_osfhandle already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __open_osfhandle already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(tolower.obj) : error LNK2005: __tolower already defined in libc.lib(tolower.obj)
LIBCMT.lib(tolower.obj) : error LNK2005: _tolower already defined in libc.lib(tolower.obj)
等等。

所 以初步估计是编译器的问题,通过网上搜索和查看msdn,原来是Visual C++ 编译器选项的关于单线程或多线程运行时例程的问题:我的那个静态库编译时/ML单线程版本的,而引用它的程序是/MT多线程版本的,他们在编译分别讲 libc.lib和LIBCMT.lib连接到各自的代码中,估计libc.lib和LIBCMT.lib只是单线程与多线程的区别,基本代码相差无几, 所以会产生链接时重定义错误;然后把编译静态库的选项/ML改成/MT就没事了。

要注意的是:/MD也是多线程版本的;被应用的用户链接库 要和应用者有相同的编译选项,/MD与/MT一起有时候会有错误的,有时候就没有,我试过这种情况;而/MD和/ML似乎是没有问题的;/MT和/ML是 肯定会有问题的。有没有其他情况就不清楚了,有兴趣的可以测试一下,^_^

如果是代码是用于多线程的,最好编译成多线程版本的,否则可能会出现一些意想不到的问题。

编译器选项设置(vc6):工程 -> 设置 -> C/C++ -> 工程选项 里可以修改
附:
下面是msdn关于Visual C++ 编译器选项的说明:

这些选项选择单线程或多线程运行时例程,指示多线程模块是否为 DLL,并选择运行时库的发布版本或调试版本。

选项说明
/MD定义 _MT 和 _DLL 以便同时从标准 .h 文件中选择运行时例程的多线程特定版本和 DLL 特定版本。此选项还使编译器将库名 MSVCRT.lib 放入 .obj 文件中。用此选项编译的应用程序静态链接到 MSVCRT.lib。该库提供允许链接器解析外部引用的代码层。实际工作代码包含在 MSVCR71.DLL 中,该库必须在运行时对于与 MSVCRT.lib 链接的应用程序可用。当 在定义了 _STATIC_CPPLIB (/D_STATIC_CPPLIB) 的情况下使用 /MD 时,它将导致应用程序通过静态多线程标准 C++ 库 (libcpmt.lib) 而非动态版本 (msvcprt.lib) 进行链接,同时仍通过 msvcrt.lib 动态链接到主 CRT。
/MDd定义 _DEBUG、_MT 和 _DLL,以便从标准 .h 文件中选择运行时例程的调试多线程特定版本和 DLL 特定版本。它还使编译器将库名 MSVCRTD.lib 放入 .obj 文件中。
/ML使编译器将库名 LIBC.lib 放入 .obj 文件中,以便链接器使用 LIBC.lib 解析外部符号。这是编译器的默认操作。LIBC.lib 不提供多线程支持。
/MLd定义 _DEBUG 并使编译器将库名 LIBCD.lib 放入 .obj 文件中,以便链接器使用 LIBCD.lib 解析外部符号。LIBCD.lib 不提供多线程支持。
/MT定义 _MT, 以便从标准头 (.h) 文件中选择运行时例程的多线程特定版本。此选项还使编译器将库名 LIBCMT.lib 放入 .obj 文件中,以便链接器使用 LIBCMT.lib 解析外部符号。创建多线程程序需要 /MT 或 /MD(或它们的调试等效选项 /MTd 或 /MDd)。
/MTd定义 _DEBUG 和 _MT。定义 _MT 会导致从标准 .h 文件中选择运行时例程的多线程特定版本。此选项还使编译器将库名 LIBCMTD.lib 放入 .obj 文件中,以便链接器使用 LIBCMTD.lib 解析外部符号。创建多线程程序需要 /MTd 或 /MDd(或它们的非调试等效选项 /MT 或 MD)。
/LD创建 DLL。将 /DLL 选项传递到链接器。链接器查找 DllMain 函数,但并不需要该函数。如果没有编写 DllMain 函数,链接器将插入返回 TRUE 的 DllMain 函数。链接 DLL 启动代码。如果命令行上未指定导出 (.exp) 文件,则创建导入库 (.lib);将导入库链接到调用您的 DLL 的应用程序。将 /Fe 解释为命名 DLL 而不是 .exe 文件;默认程序名成为基名称.dll 而不是基名称.exe。如果还未显式指定 /M 选项之一,则将默认运行时库支持更改为 /MT。
/LDd创建调试 DLL。定义 _DEBUG。

警告 不要混合使用运行时库的静态版本和动态版本。在一个进程中有多个运行时库副本会导致问题,因为副本中的静态数据不与其他副本共享。链接器禁止在 .exe 文件内部既使用静态版本又使用动态版本链接,但您仍可以使用运行时库的两个(或更多)副本。例如,当与用动态 (DLL) 版本的运行时库链接的 .exe 文件一起使用时,用静态(非 DLL)版本的运行时库链接的动态链接库可能导致问题。(还应该避免在一个进程中混合使用这些库的调试版本和非调试版本)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/448253.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Delphi面向对象编程的20条规则

Delphi面向对象编程的20条规则 作者简介 Marco Cantu是一个知名的Delphi专家,他曾出版过《精通Delphi》系列丛书,《Delphi开发手册》以及电子书《精通Pascal》(该电子书可在网上免费获得)。他讲授的课题是Delphi基础和高级开发技巧。你可以通过他…

制动失灵怎么办?

定义 制动过程中,由于制动器某些零部件的损坏或发生故障,使运动部件(或运动机械)不能保持停止状态或不能按要求停止运动的现象。 制动失灵的原因 制动失灵的关键在于制动系统无法对汽车施加足够的制动力,包括制动液管路液位不足或进入空气、制…

OpenDDS用idl生成自定义数据类型时遇到的一个问题

问题:这里会提示LNK2005重复定义的错误 解决方案: 解决后:

解决:Connect to xx.xx.xxx.xx :8081 [/xx.xx.xx.xx] failed: Connection refu sed: connect -> [H

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 1. 自行启动了个 Nenux 服务。想把本地工程推送到 个人私服,执行命令:mvn deploy 报错: Failed to…

ADOQuery 查询 删除 修改 插入

//利用combobox组件查询数据库表procedure TForm1.Button1Click(Sender: TObject);beginADOQuery1.Close;ADOQuery1.SQL.Clear;ADOQuery1.SQL.Add(select * from trim(ComboBox2.Text));ADOQuery1.Active:true;end; //查询记录procedure TForm1.Button1Click(Sender…

防爆胎,有妙招

对于大多数人来说,买车难,养车更难。许多人拥有了新车,却没有足够的知识去好好保养汽车,这实在是非常可惜。如何做好汽车的保养工作,让我们的爱车更好的为我们工作?夏天炽热的天气,是否让你为爆胎烦恼不已?…

Qt之QProcess(一)运行cmd命令

Qt提供了QProcess类,QProcess可用于完毕启动外部程序,并与之交互通信。 一、启动外部程序的两种方式: (1)一体式:void QProcess::start(const QString & program, const QStringList & arguments…

Docker 方式安装 Nexus 私服

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 1. 从Docker 官方仓库查找镜像: docker search nexus 2. 拉取镜像: docker pull 你选中的镜像的名字  pull…

shader飞线改进版

项目github地址:https://github.com/ecojust/flyline 前面写过一个飞线(基于THREE.Line进行的颜色变化),只是简单地将可视区片元颜色的alpha通道值设为1.0,不在可视区的设为0.0。效果是这样的: 做得很粗糙,而且因为线是…

转向盘失控怎么办?

定义 转向失控就是方向盘不管用了,打方向盘,但是前轮不动,不受方向盘控制。 转向失控的原因 转向失控可能因为车辆过快、酒驾、疲劳、车况不佳、雨雪路滑等,还有转向机构中有零部件脱落、损坏、卡滞时,也会使转向机构突…

Socket网络编程【获取本机IP】

//12.3.2//运行环境VS2013//获取本地IP #include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.lib")void main() { // 调用WSAStarup初始化WINsock库 WSADATA wsaData; ::WSAStartup( MAKEWORD(2,2), &wsaData);// 存放主机名的…

onresize

1 window.onresize function (ev) { 2 console.log(尺寸发生改变&#xff01;); 3 }; 4 5 window.addEventListener(resize, function (ev) { 6 console.log(尺寸发生改变&#xff01;); 7 }); 1 /*2 当屏幕的宽度>960时&#xff0c;页面的背景颜色为红色…

Vuejs:组件 slot 内容分发

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 本文是在官方文档的基础上&#xff0c;更加细致的说明&#xff0c;代码更多更全。 简单来说&#xff0c;更适合新手阅读 &#xff08;…

C++获取本机所有ip地址,可区分类型是有线无线虚拟机还是回环

一个小程序&#xff0c;可以获取本地所有ip地址&#xff0c;包括有线&#xff0c;无线&#xff0c;虚拟机&#xff0c;环回接口网卡&#xff0c;等。 如图&#xff0c;一台机器多个网卡&#xff1a; 程序执行结果&#xff1a; #include"stdio.h" #include"…

顿悟人生十一句话

一、永远不要埋怨你已经发生的事情 如果你打算忍受一件事情就闭上嘴巴吧。要么就改变它&#xff0c;要么就安静的接受它。 二、最让你忿忿不平的问题&#xff0c;就是你需要解决的问题 一个被酒后驾驶的司机撞死自己儿子的妇女&#xff0c;发起了反对酒后驾驶母亲协会…

Mybatis 在 IDEA 中使用 generator 逆向工程生成 pojo,mapper

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 使用mybatis可以逆向生成pojo和mapper文件有很多种方式&#xff0c;我以前用的是mybtais自带的generator包来生成&#xff0c;连接如下&…

控制台程序隐藏方法总结(四种)

学习计算机&#xff0c;往往先从Windows环境下学习编程&#xff0c;学习编程&#xff0c;往往从C学起&#xff0c;学习C&#xff0c;往往又从控制台程序学习&#xff0c;何为控制台&#xff0c;就是那个黑框白字的界面。对于这样一个最初认为奇陋无比而现在认为无所不能的编程平…

十大教养,让你气度非凡!

01.守时 无论是开会、赴约&#xff0c;有教养的人从不迟到。他们懂得&#xff0c;即使是无意迟到&#xff0c;对其他准时到场的人来说&#xff0c;也是不尊重的表现。 02.谈吐有节 注意从不随便打断别人的谈话&#xff0c;总是先听完对方的发言&#xff0c;然后再去反驳或者补…

mybatis :Criteria 查询、条件过滤用法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 PS&#xff1a;hibernate 中也有 Criteria 的用法&#xff0c;见另一文章&#xff1a;jpa : criteria 作排除过滤、查询 1. 包&#xf…

C++11多线程----线程管理

说到多线程编程&#xff0c;那么就不得不提并行和并发&#xff0c;多线程是实现并发&#xff08;并行&#xff09;的一种手段。并行是指两个或多个独立的操作同时进行。注意这里是同时进行&#xff0c;区别于并发&#xff0c;在一个时间段内执行多个操作。在单核时代&#xff0…