我对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”之间的区别是什么?
答案 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
,则会将其与/MT
或libcmt.lib
相关联(发布/ Debug),它包含C运行时本身,而如果使用libcmtd.lib
,它将与/MD
或msvcrt.lib
链接,它们只是DLL的导入库,不包含运行时间。
有关详细信息,请参阅https://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.120).aspx。
(请注意,在VS2015中,库已被拆分并具有新名称; C99部分名称分别为msvcrtd.lib
,libucrt.lib
,libucrtd.lib
和ucrt.lib
。)
答案 2 :(得分:0)
每个DLL
也有相应的.lib
文件。链接器链接.lib
文件,该文件具有必要的指令,指示在运行时需要从DLL
加载哪些符号。