【发布时间】:2019-03-01 12:39:06
【问题描述】:
我正在将 Visual Studio 2012 用于一个项目,并且我自己使用 Log4cxx 进行构建以用于日志记录。这两个项目都是在 Debug x64 中构建的,并且(我相信)正确链接。
两个项目的平台工具集是 Visual Studio 2012 (v110),运行时库是多线程调试 DLL (/MDd),Log4cxx 是作为动态库 (.dll) 创建和链接的。
考虑以下几点:
std::string szTestString = "Hello World!";
DOMConfigurator::configure(szTestString); // Call to Log4cxx.dll
调试时,在进入该函数之前,这是 szTestString 的值:
到目前为止一切顺利。现在我进入函数:
void DOMConfigurator::configure(const std::string& filename)
{
File file(filename);
DOMConfigurator().doConfigure(file, LogManager::getLoggerRepository());
}
当查看文件名时...
这显然不对。
如果我向前一步,我会得到一个错误:
SampleProject.exe 中 0x000007FEFD6FBDED 处的未处理异常:Microsoft C++ 异常:内存位置 0x000000000030F110 处的 std::length_error。
什么可能导致 std::string 解释发生变化?
编辑:目前我向 Log4cxx 添加了一个包装器来获取 char* 而不是 std::string 并且它成功了。然而问题仍然存在。
【问题讨论】:
-
我们需要minimal reproducible example 才能判断出问题所在。是否所有库都使用完全相同的运行时库设置构建?您使用的是静态运行时还是共享运行时?
-
我认为没有标准的应用程序二进制接口 (ABI) 允许将 C++ 对象传递给 DLL,除非它们使用相同的编译器和相同的编译器选项(C++)进行编译标准没有考虑到它,即允许 std::string 的内部表示在 STL 的实现和编译器如何编译成二进制代码之间有所不同。
-
可能是调用约定不同,或者您的项目和 DLL 各自使用不同版本的 C++ 库。您是否将这些项目中的任何一个链接到静态 C++ 运行时?
-
我在顶部附近添加了有关构建选项的信息。请告诉我是否应该添加更多详细信息(以及在哪里可以找到这些信息)。
-
检查您的项目是否实际加载了正确版本的 DLL 可能是值得的。 即如果您将这些项目与多线程调试运行时链接,然后您无意中加载了链接到非调试运行时的 DLL 的发布版本。
标签: c++ string visual-studio