如何在macOS共享库中停止重复的QMetaObject定义?

时间:2017-02-02 21:31:34

标签: c++ macos qt casting

以下qobject_cast()在macOS 10.12.2 / clang上失败(并适用于RHEL6 / gcc),因为我们的QMetaObject类有Handler个重复定义:

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等实现)中; Handler类(派生自QAction)实例由可执行文件构造并传递给共享库插件构造函数。 Handler在静态库中定义,该库内置于应用程序和共享库插件中。

This似乎描述了我的问题,并建议我需要将Handler定义编译到自己的动态库(而不是静态库)中。因为那会引起很多麻烦:

  • 这真的是我的问题:将Handler移动到共享库并在应用程序中动态加载它并且现有的插件真正解决了这个问题吗?
  • 有没有更简单的方法来解决这个问题,特别是因为这在linux(RHEL6)上运行良好?

我可以提供CMakeList片段,如果这会有所帮助,但我认为这已经足够了。

1 个答案:

答案 0 :(得分:0)

我自己可以提供一个几乎不能令人满意的答案,但是会喜欢有人提供更好的答案。简而言之:

  • Handler移动到共享库确实有用......有点。
  • 唯一的&#34;更简单&#34;我找到的解决方法是使用reinterpret_cast<Handler*>。哪个&#34;工作&#34;从某种意义上说,我没有发现任何直接的问题,但我确定不相信它,因为事实证明共享库解决方案只涉及更多(我正在考虑使用动态加载而不仅仅是链接)。

执行此操作后,我确实得到了一个QMetaObject:

DEBUG: void AbstractDataView::getSelected() Handler(0x7fa9eae0b9e0, name = "Export Metadata-7fa9eae0b9e0") 0x10e840350 0x10e840350

qobject_cast仍然失败!幸运的是,dynamic_cast<>确实有用(所以我有比reinterpret_cast<>更安全的东西),但我不能说我完全理解发生了什么。