“/ MD / MT”和“dll lib”之间的概念模糊

时间:2016-03-09 06:10:52

标签: c++ visual-studio dll

我对Windows上的运行时库选项之间的概念感到困惑。我以为我知道lib和dll之间的区别。 lib将被编译为您的代码,并且dll将在执行时动态加载。但是当我编译lib时,我不得不在/MD/MT之间做出选择。在msdn.microsoft.com上,据说:

  

使用/ MD编译的应用程序静态链接到MSVCRT.lib。   该库提供了一个启用链接器的代码层   解析外部参考。实际工作代码包含在   MSVCRversionnumber.DLL,必须在运行时可用   与MSVCRT.lib链接的应用程序。

此时我无法理解当我使用lib时我还需要动态加载一个dll。似乎使用/MD选项来构建lib将导致“动态库”,或者使用/MT选项来构建dll将导致“静态dll”。

那么“/MD/MT”和“lib vs dll”之间的区别是什么?

3 个答案:

答案 0 :(得分:3)

这方面的一个关键方面是区分构建/编译时问题和运行时问题。

在构建时,编译器和链接器需要有关如何编译和构造代码的足够信息;数据定义,函数位置等。头文件为编译器提供了大部分细节,链接器需要能够找到函数 1 来完成该过程。

如果dll也提供了lib(就像/MD的情况一样),这个lib包含链接器找到所需函数所需的最少代码,以及一些用于加载dll的附加代码运行。可以创建一个不与lib链接的程序(即使有一个dll),然后你需要在运行时加载dll(通过LoadLibrary)并修复指针(通过GetProcAddress })你需要调用的函数 1 。由于C ++库很难,因此通常不会尝试,名称修改会使这更难(使用C库通常会更容易)。

如果lib是一个没有关联dll的静态库(对于运行时这是/MT),那么lib包含运行和执行其给定功能所需的所有代码。链接器将所有必需的代码链接到目标,并且不需要额外的运行时加载。

1 我在这里松散地使用了函数这个词,但它也包含了所有外部函数。

答案 1 :(得分:1)

在这两种情况下,应用程序都会与export default class App extends React.Component { constructor(props) { super(props); this.state = { userInfo:userInfo } this.userRef = new Firebase('https://***.firebaseio.com/users/'); this.createUser = this.createUser.bind(this); this.saveUser = this.saveUser.bind(this); this.deleteUser = this.deleteUser.bind(this); } loadData(){ this.userRef.on('value', snap => { let userInfo = []; snap.forEach( data => { let userData = data.val(); userData.id = data.name(); userInfo.push(userData); }); this.setState({ userInfo }); }); this.userRef.on('child_removed', (dataSnapshot) =>{ delete this.state.userInfo[dataSnapshot.key()]; this.setState({ userInfo: this.state.userInfo }); }); } componentDidMount(){ this.loadData(); } createUser(user){ this.userRef.push(user); } saveUser(oldUser, newUser){ console.log('olduser',oldUser); console.log('newuser', newUser); // TODO - optimize this code const foundUser = _.find( this.state.userInfo, user => user.name === oldUser.name ); const foundContact = _.find( this.state.userInfo, user => user.contact === oldUser.contact ); const foundAddress = _.find( this.state.userInfo, user => user.address === oldUser.address ); const foundEmail = _.find( this.state.userInfo, user => user.email === oldUser.email ); const foundUsername = _.find( this.state.userInfo, user => user.username === oldUser.username ); const foundPassword = _.find( this.state.userInfo, user => user.password === oldUser.password ); console.log('foundUser', foundUser); console.log('foundUser.name',foundUser.name); foundUser.name = newUser.name; foundContact.contact = newUser.contact; foundAddress.address = newUser.address; foundEmail.email = newUser.email; foundUsername.username = newUser.username; foundPassword.password = newUser.password; } 文件静态关联,但如果使用.lib,则会将其与/MTlibcmt.lib相关联(发布/ Debug),它包含C运行时本身,而如果使用libcmtd.lib,它将与/MDmsvcrt.lib链接,它们只是DLL的导入库,不包含运行时间。

有关详细信息,请参阅https://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.120).aspx

(请注意,在VS2015中,库已被拆分并具有新名称; C99部分名称分别为msvcrtd.liblibucrt.liblibucrtd.libucrt.lib 。)

答案 2 :(得分:0)

每个DLL也有相应的.lib文件。链接器链接.lib文件,该文件具有必要的指令,指示在运行时需要从DLL加载哪些符号。