在尝试将使用 Visual Studio Express 2008 编译的一组代码与使用 Visual Studio 2003 编译的 .lib 链接时,我们刚刚获得了一次有趣的体验。全部使用 C++。准确地说,是在VS2003中编译成.lib的SystemC 2.2.0内核,在VS2008中编译的SystemC模型。
在链接时,我们不断收到错误,即在链接期间未找到 SystemC.lib 文件(即在 VS2003 中编译)中的一些符号。我们得到的错误是这样的(在一些变体中):
SystemC.lib(sc_port.obj) : error LNK2001: unresolved external symbol "public: vo
id __thiscall std::_String_base::_Xran(void)const " (?_Xran@_String_base@std@@QB
EXXZ)
从各种线索中挖掘,事实证明 .lib 期望找到的函数是这样的:
Undecoration of :- "?_Xran@_String_base@std@@QBEXXZ"
is :- "public: void __thiscall std::_String_base::_Xran(void)const "
虽然 VS2008 试图链接的库文件 (libcpmt.lib) 使用了不同的调用约定:
Undecoration of :- "?_Xran@_String_base@std@@SAXXZ"
is :- "public: static void __cdecl std::_String_base::_Xran(void)"
我试图弄清楚为什么会发生这种不兼容,但最后我放弃了,在 VS2008 中重新编译了完全相同的 Visual Studio 项目,并使用了 SystemC.lib 而不是 VS2003 中的那个。现在,一切都很顺利。
所以这里的基本问题是:从 VS2003 到 VS2008 发生了什么变化,会导致某些函数改变它们的调用约定?是否有一些魔术标志可以给 VS2008 中的链接器以使用其他库,其中函数具有与 VS2003 编译中相同的调用约定?
更新,到目前为止的答案摘要:微软很可能将 C++(不是 C,只是 C++)ABI 从 Visual Studio 的一个主要版本更改为下一个。库中还可能存在其他导致不兼容的更改。最好的建议是为每个版本的 VS 重新编译 .lib。本质上,只需将其以源代码形式发送给用户,并让他们使用他们碰巧安装的任何版本的 VS 在本地编译它。
通过使用以下建议发现了基本问题:
请注意,这些问题没有回答这个问题: