选择MD还是MTd????

xychzh 2011-05-29 04:13:35
先报告下我的项目结构:
首先是一个通用静态库helper.lib,提供常用的函数,模板定义
然后是引擎库engine.dll,该dll链接了helper.lib
最后是exe,加载了engine.dll

然后:我的程序只使用了win32API,DirectX API

请问我的helper.lib和engine.dll以及exe应该使用什么运行库???
我开始用的是"多线程调试(/MTd)",结果内存销毁出现了崩溃问题,改成MD就正常了
到底应该使用哪一个呢??
...全文
287 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq120848369 2011-05-30
  • 打赏
  • 举报
回复
/MT /MTd 都是将CRT的.lib以静态库形式编译到你的程序各个.obj中,体积很大,这样造成的效果就是每个模块或者说是.obj吧,都有自己的CRT来管理内存,彼此独立,所以各个模块就得自己管理自己,不能交叉。

/MD /MDd CRT就是以DLL形式,用.lib引入到你的各.obj中,所以各个模块共享这个CRT,因为各个模块都是调用这个DLL来管理内存啥的,所以跨模块没有压力。
天外来客-007 2011-05-29
  • 打赏
  • 举报
回复
Release时都是用MT!
Debug时使用MTD!
辰岡墨竹 2011-05-29
  • 打赏
  • 举报
回复
因为你用MD的话,编译出来的DLL或程序执行时需要VC运行库MSVCRTxx.DLL之类的辅助,是动态链接的。erMT则是把LIBC库静态编译进DLL里,这种编译的东西不需要依赖运行库,不受很多前者的限制。
xychzh 2011-05-29
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 ljt3969636 的回复:]
引用 5 楼 xychzh 的回复:

引用 4 楼 lifesider 的回复:
引用 3 楼 xychzh 的回复:
引用 2 楼 lifesider 的回复:
MT时,内存创建和释放必须在同一个DLL里
MD时,可以跨DLL进行内存创建和释放

比如在DLL1里使用int* ptr = new int,如果选择是创建MT,则delete ptr必须在DLL1里
如果选择是的……
[/Quote]

以前就听朋友说静态链接,什么动态链接,我当时以为说的是动态库的静态链接和动态链接,
但慢慢发现说的是MT和MD?
静态链接指的是MT,而动态链接则说的是MD吗??
super_admi 2011-05-29
  • 打赏
  • 举报
回复
学习学习。
ljt3969636 2011-05-29
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xychzh 的回复:]

引用 4 楼 lifesider 的回复:
引用 3 楼 xychzh 的回复:
引用 2 楼 lifesider 的回复:
MT时,内存创建和释放必须在同一个DLL里
MD时,可以跨DLL进行内存创建和释放

比如在DLL1里使用int* ptr = new int,如果选择是创建MT,则delete ptr必须在DLL1里
如果选择是的MD,你可以在DLL2里调用delete ……
[/Quote]



[Quote=引用 5 楼 xychzh 的回复:]

引用 4 楼 lifesider 的回复:
引用 3 楼 xychzh 的回复:
引用 2 楼 lifesider 的回复:
MT时,内存创建和释放必须在同一个DLL里
MD时,可以跨DLL进行内存创建和释放

比如在DLL1里使用int* ptr = new int,如果选择是创建MT,则delete ptr必须在DLL1里
如果选择是的MD,你可以在DLL2里调用delete ……
[/Quote]

adlay在你一个帖子里已经回复了

1.静态连接整体替换到哪个模块,所以你静态连接时,每个模块用自己的CRT
2.动态连接时,内存的管理操作将集中在该操作所在dll(mscrt80.dll)中进行,所以你能跨模块...
lifesider 2011-05-29
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xychzh 的回复:]
引用 4 楼 lifesider 的回复:
引用 3 楼 xychzh 的回复:
引用 2 楼 lifesider 的回复:
MT时,内存创建和释放必须在同一个DLL里
MD时,可以跨DLL进行内存创建和释放

比如在DLL1里使用int* ptr = new int,如果选择是创建MT,则delete ptr必须在DLL1里
如果选择是的MD,你可以在DLL2里调用delete p……
[/Quote]

其实从微软的MSDN上可以看到,/MT是静态版本,没有定义_DLL宏,而/MD才是针对DLL的,可以动态解析符号
http://msdn.microsoft.com/zh-cn/library/2kzt1wy3(VS.80).aspx

至于上面我的解释,主要是在工作中总结的经验,原来也遇到过这种问题,一旦在外部释放内存时,便会报heap corruption,所以也认为其实是静态与动态的区别导致的
nakedavril 2011-05-29
  • 打赏
  • 举报
回复
mkk
xengine-qyt 2011-05-29
  • 打赏
  • 举报
回复
发布版本MT,后面有D的是带有调试信息的,也就是 必须有 VC运行库才能在其他平台上使用!
xychzh 2011-05-29
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 lifesider 的回复:]
引用 3 楼 xychzh 的回复:
引用 2 楼 lifesider 的回复:
MT时,内存创建和释放必须在同一个DLL里
MD时,可以跨DLL进行内存创建和释放

比如在DLL1里使用int* ptr = new int,如果选择是创建MT,则delete ptr必须在DLL1里
如果选择是的MD,你可以在DLL2里调用delete ptr


1:一般什么情况下使用MT,什……
[/Quote]

1:原来MT竟是把各模块的内存管理给划上了分界线
2:您确信这一说法么?我仍有些不疑惑,因为我到现在没听过别人这么解释过.
lifesider 2011-05-29
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 xychzh 的回复:]
引用 2 楼 lifesider 的回复:
MT时,内存创建和释放必须在同一个DLL里
MD时,可以跨DLL进行内存创建和释放

比如在DLL1里使用int* ptr = new int,如果选择是创建MT,则delete ptr必须在DLL1里
如果选择是的MD,你可以在DLL2里调用delete ptr


1:一般什么情况下使用MT,什么情况下使用MD?
2:您看我应该使用……
[/Quote]

其实你使用VS新建DLL时,就能发现默认选项是MD(DEBUG下是MDD)。这就是说我们通常认为一个进程里操作内存都是可行的,并不一定要强制在某一个DLL里。

不过,对于某些特殊情况,比如你操作的东西并不想别人去释放,或者你使用了某些管理,这些就需要使用MT。这就像,你对某一对象进行管理,当你提供Create接口时,通常应该提供Release接口。而不是外部使用者调用delete关键字,因为如果一旦你实现的DLL的有特别之外时,外部强制使用delete便会失败(比如你使用malloc,或者首先创建固定数量的对象于进程堆上,然后只是放置对象,并返回其地址,即使用placement new)
xychzh 2011-05-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 lifesider 的回复:]
MT时,内存创建和释放必须在同一个DLL里
MD时,可以跨DLL进行内存创建和释放

比如在DLL1里使用int* ptr = new int,如果选择是创建MT,则delete ptr必须在DLL1里
如果选择是的MD,你可以在DLL2里调用delete ptr
[/Quote]

1:一般什么情况下使用MT,什么情况下使用MD?
2:您看我应该使用哪一个?
lifesider 2011-05-29
  • 打赏
  • 举报
回复
MT时,内存创建和释放必须在同一个DLL里
MD时,可以跨DLL进行内存创建和释放

比如在DLL1里使用int* ptr = new int,如果选择是创建MT,则delete ptr必须在DLL1里
如果选择是的MD,你可以在DLL2里调用delete ptr
xspace_time 2011-05-29
  • 打赏
  • 举报
回复
MSDN VC6.0

Command Line Project Settings Description
/MD Multithreaded DLL Defines _MT and _DLL so that both multithread- and DLL-specific versions of the run-time routines are selected from the standard .H files. This option also causes the compiler to place the library name MSVCRT.LIB into the .OBJ file.
Applications compiled with this option are statically linked to MSVCRT.LIB. This library provides a layer of code that allows the linker to resolve external references. The actual working code is contained in MSVCRT.DLL, which must be available at run time to applications linked with MSVCRT.LIB.
/MDd Debug Multithreaded DLL Defines _DEBUG, _MT, and _DLL so that debug multithread- and DLL-specific versions of the run-time routines are selected from the standard .H files. It also causes the compiler to place the library name MSVCRTD.LIB into the .OBJ file.
/ML Single-Threaded Causes the compiler to place the library name LIBC.LIB into the .OBJ file so that the linker will use LIBC.LIB to resolve external symbols. This is the compiler’s default action. LIBC.LIB does not provide multithread support.
/MLd Debug Single-Threaded Defines _DEBUG and causes the compiler to place the library name LIBCD.LIB into the .OBJ file so that the linker will use LIBCD.LIB to resolve external symbols. LIBCD.LIB does not provide multithread support.
/MT Multithreaded Defines _MT so that multithread-specific versions of the run-time routines are selected from the standard header (.H) files. This option also causes the compiler to place the library name LIBCMT.LIB into the .OBJ file so that the linker will use LIBCMT.LIB to resolve external symbols. Either /MT or /MD (or their debug equivalents /MTd or /MDd) is required to create multithreaded programs.
/MTd Debug Multithreaded Defines _DEBUG and _MT. Defining _MT causes multithread-specific versions of the run-time routines to be selected from the standard .H files. This option also causes the compiler to place the library name LIBCMTD.LIB into the .OBJ file so that the linker will use LIBCMTD.LIB to resolve external symbols. Either /MTd or /MDd (or their non-debug equivalents /MT or MD) is required to create multithreaded programs.
/LD Not applicable Creates a DLL.
Passes the /DLL option to the linker. The linker looks for, but does not require, a DllMain function. If you do not write a DllMain function, the linker inserts a DllMain function that returns TRUE.
Links the DLL startup code.
Creates an import library (.LIB), if an export (.EXP) file is not specified on the command line; you link the import library to applications that call your DLL.
Interprets /Fe as naming a DLL rather than an .EXE file; the default program name becomes basename.DLL instead of basename.EXE.
Changes default run-time library support to /MT if you have not explicitly specified one of the /M options
/LDd Not applicable Creates a debug DLL. Defines _DEBUG.


MSDN VC2008 编译和调用参数一样 参数是针对调用类型的

/MD使用 MSVCRT.lib 创建多线程 DLL
/MDd使用 MSVCRTD.lib 创建调试多线程 DLL
/MT使用 LIBCMT.lib 创建多线程可执行文件
/MTd使用 LIBCMTD.lib 创建调试多线程可执行文件

/MD使用 MSVCRT.lib 编译以创建多线程 DLL
/MDd使用 MSVCRTD.lib 编译以创建调试多线程 DLL
/MT使用 LIBCMT.lib 编译以创建多线程可执行文件
/MTd使用 LIBCMTD.lib 编译以创建调试多线程可执行文件

64,650

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧