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

时间:2014-09-14 16:03:16

标签: c++ visual-studio-2010

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

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

如何设置怪异:

  1. 在项目的预处理器定义
  2. 中的库内设置PRETTY_LOG
  3. 在EXE项目中取消 PRETTY_LOG
  4. 编译构建库的整个解决方案,然后编译EXE
  5. 在可执行文件的代码中实例化CStudentModeler时,奇怪就开始了。此时,调试器似乎对它应该使用哪个版本的CStudentModeler感到困惑,并且将鼠标悬停在IDE中的变量上会导致真正令人困惑的结果。当EXE运行时,它也会出现内存损坏。

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

    我的问题如下:

    1. 我是否正确识别了问题?
    2. 是否可以根据编译器指令使库功能成为可选项,但不能破坏使用该库的其他项目?
    3. 根据库的编译方式,确保使用库的项目采用正确的启用功能的正确方法是什么?
    4. VS2010编译/链接过程的任何部分都没有警告我这个看似巨大的错误?
    5. 为了这个测试,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 个答案:

答案 0 :(得分:1)

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