gpt4 book ai didi

c++ - 由于库与 EXE 项目中的编译器指令不匹配而导致内存损坏

转载 作者:行者123 更新时间:2023-11-28 06:41:51 25 4
gpt4 key购买 nike

我有一个库 StudentModelLib,其中 CStudentModeler 是库中的主要类。它有一个日志记录选项,我以是否启用 PRETTY_LOG 为条件。如果仅当 PRETTY_LOG 启用时,我是否包含 CPrettyLogger、初始化它(稍后)和/或实际记录内容。

同一解决方案中的另一个项目 StudentModel2,静态链接到 StudentModelLib。它包含库中的 StudentModeler.h 并在运行时实例化 CStudentModeler

如何设置怪异度:

  1. 在项目预处理器定义的库中设置PRETTY_LOG
  2. 在 EXE 项目中取消设置 PRETTY_LOG
  3. 编译整个解决方案,构建库,然后是 EXE

CStudentModeler 在可执行文件的代码中被实例化时,怪事就开始了。此时,调试器似乎对它应该使用哪个版本的 CStudentModeler 感到困惑,并且将鼠标悬停在 IDE 中的变量上会导致真正令人困惑的结果。当 EXE 运行时,它还会显示内存损坏。

我的假设是编译库的 CStudentModeler 有一个 prettyLogger 成员,但编译后的 EXE 使用禁用指令的 .h 文件,它假定 CStudentModeler 有一个 prettyLogger 成员。我猜内存损坏的发生是因为库和 EXE 对于类的成员变量在堆上的位置有不同的定义。

我的问题如下:

  1. 我是否正确识别了问题?
  2. 是否可以根据编译器指令使库功能可选,但不会破坏使用该库的其他项目?
  3. 确保使用库的项目根据库的编译方式假定正确启用的功能的正确方法是什么?
  4. 为什么 VS2010 编译/链接过程的任何部分都没有警告我这个看似巨大的错误?

为了这个测试,CPrettyLogger 有一个空的默认构造函数,所有其他相关的代码都被注释掉了。简单地实例化它会导致错误。

StudentModeler.h

这是库的一部分,包含条件成员变量。

class CStudentModeler : public CDataProcessor2
{
// Configuration variables
string student_id;

// Submodules
CContentSelector contentSelector;
EventLog eventLog;

#ifdef PRETTY_LOG
CPrettyLogger prettyLogger; // <--- the problem?
#endif

// Methods
void InitConcepts();
void InitLOs();

public:
CStudentModeler( string sm_version, string session_id, string url,
string db_user, string db_password, string db_name,
SMConfig config );

~CStudentModeler();
}

最佳答案

  1. 看来您的评估是正确的。
  2. 是的,这是可能的。不要使外部可见的声明依赖于预处理指令,你应该没问题。内部的东西可以随心所欲地配置,但接口(interface)应该是一成不变的。在您的情况下,库应该导出一个接口(interface)和一个类工厂。客户端要么不知道所选实例是否具有附加功能,要么只能通过可能容易出错的接口(interface)访问它。如果失败,则不支持。
  3. 如果您按照我在 (2) 中的建议进行操作,则无需这样做。如果您仍然想要,在库中有一个宏扩展为 library_options_opt1_yes_opt2_no_opt3_42_... 的变量名称,并让 header 中的客户端代码引用它。如果不匹配,您将遇到链接错误。
  4. Thr C++ 标准特别允许编译器在您执行此类操作时不警告您。对于编译器来说,这实际上并不容易。相应的规则称为一个定义规则。

关于c++ - 由于库与 EXE 项目中的编译器指令不匹配而导致内存损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25835199/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com