【发布时间】:2020-12-02 14:06:51
【问题描述】:
我正在将一个项目集成到另一个项目中,并且在使用 QT 时遇到了一些构建问题。 我得到的问题是在声明 QMetaType::Bool 的 moc 文件中生成了一行。 它说“'int'之前的预期不合格ID”,然后是由该错误引起的几个括号错误。 根据我的研究,其他人说这是由于项目中将 Bool 定义为 int 的其他地方的 xlib.h。 我已经尝试过“#undef Bool”行,但它似乎不起作用。当我将它放在调用堆栈中最近的 cpp 文件的标题中时,上面提到的错误消失了,但它也破坏了我在所述 cpp 文件中声明的所有对象,给了我一堆未定义的引用错误,我知道不是真的。 所以两个问题:
-
尽管我显式调用了 QMetaType:: 命名空间,但为什么我从不同的库中获取了不同的 Bool 定义却收到错误消息?
-
有解决此问题的其他方法的想法吗?
编辑:这是在 moc 文件中导致问题的功能块。
#undef QT_MOC_LITERAL
static const uint qt_meta_data_FUNCTIONNAMEREDACTED[] = {
// content:
7, // revision
0, // classname
0, 0, // classinfo
6, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
// slots: name, argc, parameters, tag, flags
1, 0, 44, 2, 0x0a /* Public */,
3, 1, 45, 2, 0x0a /* Public */,
5, 1, 48, 2, 0x0a /* Public */,
6, 0, 51, 2, 0x0a /* Public */,
7, 1, 52, 2, 0x0a /* Public */,
9, 1, 55, 2, 0x0a /* Public */,
// slots: parameters
QMetaType::Void,
QMetaType::Void, QMetaType::Int, 4,
QMetaType::Void, QMetaType::Int, 4,
QMetaType::Void,
QMetaType::Void, QMetaType::Bool, 8,
QMetaType::Void, QMetaType::QString, 10,
0 // eod
};
【问题讨论】:
-
关于 1.:
xlib.h的问题不是Bool,而是它被定义为宏(例如#define Bool int)。预处理(替换宏的步骤)继承自 C 并且完全与命名空间无关。这就是为什么(尤其是这样的)宏在 C++ 中被认为是最糟糕的。不幸的是,当xlib.h成立时,C++ 还没有发明。#undef Bool的提示是正确的,但您必须将其插入正确的位置(QMetaType::Bool第一次出现之前和#include <xlib.h>之后)。 -
结合 MOC 生成的代码,这可能不是那么容易。一种可能的解决方法:运行一次 MOC,然后编辑生成的文件。 (并防止 MOC 覆盖每个构建中的文件。)
-
为了澄清起见,错误来自以下行:“QMetaType::Void, QMetaType::Bool, 8,” 这是一个生成的 moc_ 文件,不是我写的文件。还有 Scheff,他的评论刚刚出现:生成这个 moc 的 cpp 文件,我把 undef 行放在这里,它什么也没做。我在这个 cpp 文件的头文件中尝试了它,它通过我上面提到的那些未定义的引用错误破坏了它。
-
如果
#undef Bool不起作用,则说明位置不正确。您知道一般预处理的工作原理吗? -
如果
#undef Bool在某处无效,我会专门检查发生此错误的c++文件。(即使错误在标题中弹出,您也必须专注于c++已编译的文件。)您可以使用-E编译此特定文件,并将获得一个(非常长的)新源文件,其中每个宏替换都已完成。评估这肯定是非常乏味的。另一个选项是命令行参数。 (忘了哪个)它显示了执行的#includes。因此,您可能会意识到什么包括什么顺序。有了这个,你应该就能解开这个谜题了。