6

我正在使用该工具为我的 D-Bus 服务器qdbusxml2cpp生成D-Bus 适配器类。但是,它有以下缺点:

  • 代码生成一次,然后你不应该修改它。但是如果我们必须进行更改(见下文)然后 XML 更改(当然以向后兼容的方式)怎么办?

  • 假设“适配者”具有与 D-Bus 接口完全相同的功能和签名。就我而言,这并不完全正确,例如,某些方法的名称不同。因为生成的代码使用QMetaObject::invokeMethod,这仅在运行时被检测到。如果将来可能需要重新生成生成的代码,我们也不能明智地修改它。

qdbusxml2cpp在我看来,如果能生成一个抽象类,只是一个标题,其中所有方法都是纯虚拟的,那就更好了。然后我可以编写该类的实现,它只调用适配者上的正确方法,而无需通过 Qt 元类型系统。这解决了两个问题:

  • 如果 XML 发生变化,我们只需重新生成标头。现在编译器会抱怨,直到我们正确实现新接口。

  • 我们可以自由地在“adaptee”类上调用我们喜欢的任何函数,而不是维护与公共 D-Bus 接口中完全相同的签名。

我找不到qdbusxml2cpp执行上述操作的任何工具或叉子。在我自己编写之前,上述方法是否存在我可能忽略的设计或技术问题?也许与抽象类或纯虚函数相关的元类型系统的限制?

请注意,我不仅需要使用方法,还需要使用属性和信号。

我还考虑编写一个“中间”适配器来包装“适配器”并提供 D-Bus 适配器所期望的确切接口,但 D-Bus 适配器仍将使用元类型系统和运行时检查。我们当然可以做得更好。

4

1 回答 1

4

正如你所发现的,没有办法直接做你想做的事qdbusxml2cpp。这意味着我们在这里有一些选项,您已经列出了一些选项:

qdbusxml2cpp在我看来,如果能生成一个抽象类,只是一个标题,其中所有方法都是纯虚拟的,那就更好了。

这似乎没有什么大问题,尽管某些工具/IDE 可能无法很好地使用它。这样做的一个缺点是,无论何时发生变化,您都必须确保更新 C++ 源代码的所有部分,而不仅仅是您的标头,例如,如果有样板文件在添加新方法时必须更改。

代码生成一次,然后你不应该修改它。但是如果我们必须进行更改(见下文)然后 XML 更改(当然以向后兼容的方式)怎么办?

根据代码生成器的工作情况,我有时会发现简单地将生成的代码用作起点,然后从那里简单地修改它会更容易。大多数更改通常都非常简单。

您可以做的另一种选择是使用不同的库来进行 DBus 通信。

我使用(并维护)dbus-cxx;包含一个工具(dbus-cxx-xml2cpp),它生成类似于输出qdbusxml2cpp的适配类,适配类只调用一个不同的类来处理实际响应。缺点是 xml2cpp 工具不是那么聪明,并且不会总是输出正确的代码。并且要在 Qt 应用程序中使用 dbus-cxx,您需要关闭 Qt 关键字。但是,它确实具有使用模板函数的优势,因此如果您的签名不正确,您将收到编译错误。

不幸的是,实际上并没有一个很好的“正确”方法来做到这一点,所以恐怕我没有“这样做”的答案。

于 2018-03-24T20:18:43.553 回答