我们在链接时偶然发现了一个非常模糊的行为。首先是非常常见的链接器错误:
错误LNK2005:" public:void __cdecl std :: basic_ofstream< char,struct 的的std :: char_traits<炭> > ::`vbase destructor'(void)" ( ?? _ D?$ basic_ofstream @ DU?$ char_traits @ D @ std @@@ std @@ QEAAXXZ )已经 定义于 osgDBd.lib(osg80-osgDBd.dll)d:\ temp \ osg_lnk2005_ofstream \ ConsoleApplication1 \ ConsoleApplication1 \ libboost_unit_test_framework-vc110-mt-gd- 1_53.lib(unit_test_parameters.obj)
lols的解码名称:
public:void __cdecl std :: basic_ofstream< char,struct std :: char_traits< char> > ::`vbase destructor'(void)__ ptr64
情况:我们正在联系反对加强单元测试框架和Openscenegraphs' osgDB库并在我们的代码中引入行std::ofstream out;
,我们得到上面的链接器错误。
这是代码,
#pragma comment(lib, "osgDBd.lib")
//#pragma comment(lib, "boost_unit_test_framework-vc110-mt-gd-1_53.lib") // dynamic: works
//#pragma comment(lib, "libboost_unit_test_framework-vc110-mt-sgd-1_53.lib") // fails, mixing static and dynamic crt
//#pragma comment(lib, "libboost_unit_test_framework-vc110-sgd-1_53.lib") // fails, mixing static and dynamic crt
#pragma comment(lib, "libboost_unit_test_framework-vc110-mt-gd-1_53.lib")
/*
#define BOOST_PROGRAM_OPTIONS_DYN_LINK
#define BOOST_ALL_DYN_LINK
#define BOOST_TEST_DYN_LINK
*/
#include <fstream>
#include <osgDB/WriteFile>
#include <boost/test/unit_test.hpp>
int main(int argc, char* argv[])
{
std::ofstream out;
return 0;
}
(为了清晰起见,我使用了pragma链接)
当我们将boost链接为静态(但是使用动态CRT)时,会生成上面的链接器错误,当使用动态提升版本时,它会消失。
所有lib都使用/ MDd编译为debug,因此不应发生运行时混合。
虽然osgDB的fstream注意到只应该使用osgDB::ofstream
,但我不确定是什么原因导致了这个问题。
osg的fstream标题在这里(如果重要):
namespace osgDB
{
class OSGDB_EXPORT ofstream : public std::ofstream
{
public:
ofstream();
explicit ofstream(const char* filename,
std::ios_base::openmode mode = std::ios_base::out);
~ofstream();
void open(const char* filename,
std::ios_base::openmode mode = std::ios_base::out);
};
}
在这种情况下,所有邪恶的根源是boost是静态的,因此将它的依赖性带入我的可执行文件中吗?当boost是动态的时,import lib只包含导出的符号,但是当boost是静态的时,一切都被导入到我的二进制文件中,然后与osgDB通过dll导出整个类引入的隐式导出的std :: ofstream冲突?