【问题标题】:std::string gets corrupted/change structure when passed to a library传递给库时,std::string 会损坏/更改结构
【发布时间】: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


【解决方案1】:

当库在“发布”模式下编译并且您尝试在“调试”模式下运行应用程序时,通常会出现此问题。

将两个组件(即 DLL 和应用程序)保持在相同的模式(发布或调试)。
确保 DLL 和应用程序的“代码生成”属性值相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-10
    • 1970-01-01
    • 2015-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多