【问题标题】:Preprocessor switch determining version of a class预处理器开关确定类的版本
【发布时间】:2009-07-14 17:01:01
【问题描述】:

我有一个类有两种可能的实现,这取决于预处理器开关。我处理这个问题的方法是创建“src\CompSwitch1\class.h”和“src\CompSwitch2\class.h”。在我的标准包含文件中,我使用

   #ifdef CompSwitch1
        #include "CompSwitch1\class.h"
    #elif CompSwitch2
        #include "CompSwitch2\class.h"
    #else
        #error "Specify CompSwitch1 or CompSwitch2"
    #endif

这适用于我的大多数需要两个版本的课程。但是,在其中一个上,我收到链接器错误(lnk2019:未解析的外部符号)。我正在使用 MS Visual Studio 2005 和 2008,它们都出现了。

在 .h 文件的顶部,我针对预处理器选项进行了测试。 此外,虽然为了简洁起见,我只引用了 .h 文件,但在相应的目录中还有一个 .cpp 文件用于每个文件。

【问题讨论】:

  • LNK2019 可能正在发生,因为您的#include 引入的类的实现(在适当的 *.cpp 中)没有被编译。您能否提供有关错误的更多信息(哪个符号、它在哪个文件中定义等)?

标签: c++ visual-studio linker c-preprocessor


【解决方案1】:

听起来您可能已经包含了其中一个类的头文件,但链接了另一个类的目标文件,或者两者都没有

【讨论】:

    【解决方案2】:

    确实应该是#ELIF DEFINED(CompSwitch2)。否则,您假设“CompSwitch2”已定义为 1 ...

    【讨论】:

    • 不一定。在布尔上下文中考虑时,未定义的宏被评估为 0。
    • 但是定义的值没有被认为是 1?就我个人而言,我总是做定义的事情......因为我过去没有这样做而遇到过奇怪的问题/
    【解决方案3】:

    在 cpp 实现文件中包含以下预处理器行后,尝试将它们放入其中:

    //in compswitch1.cpp
    #ifndef CompSwitch1
    # error "inconsistent header included"
    #endif
    
    //in compswitch2.cpp
    #ifndef CompSwitch2
    # error "inconsistent header included"
    #endif
    

    如果你编译了错误的 header/cpp 对,你至少应该得到编译错误而不是链接错误。有很多更容易识别/修复;)

    另一种可能性是 cpp 文件根本不包含在编译中。在 cpp 文件中放置一个消息 pragma 以查看它们是否被编译:

    #pragma message( "Compiling " __FILE__ ) 
    

    或者尝试在构建目录中识别是否创建了与 cpp 编译单元相关的目标文件。

    希望对您有所帮助,
    风向标

    【讨论】:

      【解决方案4】:

      您可以使用预处理的 cpp 文件(扩展所有包含和宏的阶段)。

      在 VS 2008 中,在解决方案资源管理器->属性->C++->预处理器中右键单击您的文件,然后设置“生成预处理文件”设置“带行号 (/P)”。 之后,再次右键单击您的文件并选择“编译”。扩展名为“i”的文件(例如 main.i)将在 cpp 所在的同一目录中创建。打开它,看看包含了哪个包含文件。

      这种方法很少能解决硬编译问题(例如,系统头文件中的某些宏替换了代码中的某些内容)。

      【讨论】:

        猜你喜欢
        • 2011-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-11
        • 2015-10-21
        • 2013-09-25
        相关资源
        最近更新 更多