Qt 信号封装在 ifdef 中
我的 Qt 项目链接到一个仅限 Linux 的库。当项目在 Linux 下运行时,我希望使用该库中定义的类型在事件上触发信号。不过,我遇到的一个难题是该项目还必须在 Windows 中构建。显然,这个信号和捕获它的插槽在 Windows 中不存在,但这没关系。然而,我发现 Qt 的 moc 工具无法识别发出信号的代码周围是否存在 #ifdef __linux__
的问题。我的代码如下所示:
[SomeFile.h]
#ifdef __linux__
signals:
void SomeSignal(SomeTypeDefinedInTheLinuxLibrary);
#endif
[SomeFile.cpp]
#ifdef __linux__
emit SomeSignal(someObject);
#endif
当我尝试使用 g++ 编译此代码时,出现错误: SomeFile.cpp:(.text+0x858c): 对 SomeFile::SomeSignal(SomeTypeDefinedInTheLinuxLibrary) 的未定义引用
有什么想法可以让 moc 和 #ifdefs 很好地协同工作吗?
My Qt project links to a library that is linux-only. When the project is run under linux, I wish to have a signal fired on an event using a type defined in that library. A complication that I have, though, is that the project must also build in Windows. Obviously, this signal and the slot catching it wouldn't exist in Windows, and that's fine. I am, however, finding issues with Qt's moc tool failing to recognize the existence of an #ifdef __linux__
around the code that emits the signal. My code looks like this:
[SomeFile.h]
#ifdef __linux__
signals:
void SomeSignal(SomeTypeDefinedInTheLinuxLibrary);
#endif
[SomeFile.cpp]
#ifdef __linux__
emit SomeSignal(someObject);
#endif
When I attempt to compile this with g++, I get the error:SomeFile.cpp:(.text+0x858c): undefined reference to SomeFile::SomeSignal(SomeTypeDefinedInTheLinuxLibrary)
Any ideas how to get moc and #ifdefs to play well together?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
更好的解决方案是始终提供信号并注释掉 Windows 上触发信号的代码。这样,公共 API 在所有平台上都是相同的。
[编辑] moc 工具真的很愚蠢。它实际上并不理解代码;相反,它只对某些模式做出反应。这就是它忽略
#ifdef
的原因。要解决此问题,请包装类型或使用
#ifndef __linux__
并在其中定义您自己的虚拟类型,以便它可以在 Windows 上编译。由于信号不会在 Windows 上发出,因此永远不会使用该插槽,因此任何使代码编译的类型都应该没问题。A much better solution is to always provide the signal and just comment out the code that fires it on Windows. That way, the public API is the same on all platforms.
[EDIT] The moc tool is really dumb. It doesn't actually understand the code; instead it just reacts on certain patterns. That's why it ignores the
#ifdef
.To solve the issue, wrap the type or use
#ifndef __linux__
and define your own dummy type in there so it compiles on Windows. Since the signal won't be emitted on Windows, the slot will never be used so any type that makes the code compile should be fine.使用 Qt 5.3 至少使用 Visual Studio,我能够将预处理器宏传递给 moc 工具。为了完成这项工作,我必须对 Visual Studio 项目文件进行文本编辑,并手动为每个文件添加命令行参数,以便将预处理器参数传递给 moc 工具。您可以使用 -D[Pre-Processor],即 -DSPECIAL_BUILD 或 -DSPECIAL_BUILD=1,并且 moc 编译器足够智能,可以查看代码中的 #if SPECIAL_BUILD 检查,而不是尝试 moc 这些部分。
只需搜索“moc.exe”并为每个配置添加适当的参数即可。
With Qt 5.3 at least using Visual Studio, I am able to pass pre-processor macros to the moc tool. In order to make this work, I had to text edit my Visual Studio project file and manually add command line arguments for each file in order to hand the pre-processor arguments to the moc tool. You can use -D[Pre-Processor], i.e. -DSPECIAL_BUILD or -DSPECIAL_BUILD=1, and the moc compiler is smart enough to see the #if SPECIAL_BUILD checks in your code and not try to moc those parts.
Just search for "moc.exe" and add the appropriate parameters for each configuration.