C++ 库与EXE项目中的编译器指令不匹配导致内存损坏
我有一个库C++ 库与EXE项目中的编译器指令不匹配导致内存损坏,c++,visual-studio-2010,C++,Visual Studio 2010,我有一个库StudentModelLib,其中CStudentModeler是库中的主类。它有一个日志选项,我根据是否启用PRETTY\u LOG设置了条件。如果只有启用了PRETTY_LOG,我才能包括CPrettyLogger,初始化它(稍后),和/或实际记录事情 同一解决方案中的另一个项目,StudentModel2,静态链接到StudentModelLib。它包括库中的StudentModeler.h,并在运行时实例化CStudentModeler 如何设置古怪: 在项目的预处理器定义的
StudentModelLib
,其中CStudentModeler
是库中的主类。它有一个日志选项,我根据是否启用PRETTY\u LOG
设置了条件。如果只有启用了PRETTY_LOG
,我才能包括CPrettyLogger
,初始化它(稍后),和/或实际记录事情
同一解决方案中的另一个项目,StudentModel2
,静态链接到StudentModelLib
。它包括库中的StudentModeler.h
,并在运行时实例化CStudentModeler
如何设置古怪:
PRETTY\u LOG
PRETTY\u LOG
CStudentModeler
时,这种奇怪就开始了。此时,调试器似乎对应该使用哪个版本的CStudentModeler
感到困惑,并且将鼠标悬停在IDE中的变量上会导致非常混乱的结果。当EXE运行时,也会出现内存损坏
我的假设是,已编译库的CStudentModeler
有一个prettyLogger
成员,但已编译的EXE使用.h文件并禁用了指令,并且它假设CStudentModeler
没有prettyLogger
成员。我猜发生内存损坏是因为库和EXE对类的成员变量在堆中的位置有不同的定义
我的问题如下:
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();
}
CStudentModeler类:公共CDATA处理器2
{
//配置变量
字符串学生id;
//子模块
CContentSelector内容选择器;
事件日志事件日志;
#ifdef PRETTY_LOG
CPrettyLogger prettyLogger;//
看来你的评估是正确的
是的,这是可能的。不要使外部可见的声明依赖于预处理指令,您应该可以。内部内容可以根据您的需要进行配置,但接口应该是固定的。在您的情况下,库应该导出接口和类工厂。客户端应该不知道所选实例是否ce有一个附加功能,或者只能通过可能出错的接口访问它。如果它失败,则不支持它
如果你按照我在(2)中的建议去做,你就不需要这样做。如果你仍然想,在库中有一个变量名,宏可以扩展到library\u options\u opt1\u yes\u opt2\u no\u opt3\u 42\u…
,并且让客户端代码在头中引用它。如果不匹配,你会有一个链接错误
TrC++标准明确允许编译器不警告你如果你做这些事情。实际上对于编译器来说并不容易。相应的规则被称为一个定义规则。