如何在macOS共享库中停止重复的QMetaObject定义
How can I stop duplicate QMetaObject definitions across macOS shared libraries?
以下qobject_cast()
在macOS 10.12.2/clang上失败(在RHEL6/gcc上工作),因为我们的Handler
类有重复的QMetaObject
定义:
void AbstractDataView::getSelected()
{
qDebug() << Q_FUNC_INFO << QObject::sender()
<< QObject::sender()->metaObject()
<< &Handler::staticMetaObject;
Handler *h = qobject_cast<Handler*>(QObject::sender());
if(h)
this->getSelected(h);
else
qDebug() << "could not find handler to get selected data points"
<< h;
}
以上打印:
DEBUG: void AbstractDataView::getSelected() Handler(0x7f9674011780, name = "Export Metadata-7f9674011780") 0x1009d4930 0x1113a1310
DEBUG: could not find handler to get selected data points QObject(0x0)
上述代码位于我们的应用程序加载的共享库插件中(通过Qt插件宏Q_DECLARE_INTERFACE
等实现);CCD_ 5类(源自QAction
)实例由可执行文件构造并传递给共享库插件构造函数。Handler
是在一个静态库中定义的,该静态库内置于应用程序和共享库插件中。
这似乎描述了我的问题,并表明我需要将Handler
定义编译到它自己的动态库(而不是静态库)中。因为这会引起很多头痛:
- 这真的是我的问题吗:将
Handler
移动到共享库并在应用程序和现有插件中动态加载它真的能解决这个问题吗 - 真的没有更简单的方法来解决这个问题吗,特别是因为它在linux(RHEL6)上运行良好
如果有帮助的话,我可以提供CMakeList片段,但我认为这已经足够长了。
我自己可以提供一个勉强令人满意的答案,但我希望有人能提供更好的答案。简而言之:
- 将
Handler
移动到共享库确实有效。。。有点 - 我发现唯一"更简单"的解决方法是使用
reinterpret_cast<Handler*>
。从某种意义上说,这"有效",我没有发现直接的问题,但我肯定不相信它,而且事实证明,共享库解决方案只涉及很少(我考虑使用动态加载而不仅仅是链接)
这样做之后,我确实得到了一个QMetaObject:
DEBUG: void AbstractDataView::getSelected() Handler(0x7fa9eae0b9e0, name = "Export Metadata-7fa9eae0b9e0") 0x10e840350 0x10e840350
但是qobject_cast
仍然失败!幸运的是,dynamic_cast<>
确实有效(所以我有比reinterpret_cast<>
更安全的东西),但我不能说我完全理解发生了什么。
相关文章:
- 在提升multi_index容器中,是否定义了"default index"?
- #定义c-预处理器常量..我做错了什么
- 用C++中的一个变量定义一个常量
- 部分定义/别名模板模板参数
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- #为""定义宏;静态";针对不同的上下文
- QMetaObject invokeMethod的基于函数指针的语法
- 如何确保C++函数在定义之前声明(如override关键字)
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在命名空间中定义函数还是限定函数
- 此代码是否违反一个定义规则
- 编译C++时未定义的引用
- 不同翻译单元中不可重载的非内联函数定义
- 为什么在定义函数之前先声明它
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 在类定义之后定义一个私有方法
- 使用用户定义函数的字符串反转
- 如何在macOS共享库中停止重复的QMetaObject定义
- 为什么我可以通过自定义对话框获得"QMetaObject::connectSlotsByName: No matching signal"?