【问题标题】:How to write Qt plugin system with bindings in other languages?如何编写带有其他语言绑定的 Qt 插件系统?
【发布时间】:2012-08-11 12:15:33
【问题描述】:

我正在用 Qt 编写一个我想用插件扩展的应用程序。 我的应用程序还有一个插件将使用的库。所以,我需要一种双向通信。基本上,插件可以调用库,我加载插件的应用程序会调用它们。

现在,我的库是用 C++ 编写的,所以它有一些类。插件可以包含头文件,链接到它并使用它。我的接口也有一个头文件,它是插件必须实现的抽象基类。他们还应该导出一个函数,该函数将返回指向该类的指针,并使用 C 链接。

到目前为止,我相信一切都清楚了,一个标准的插件界面。但是,有 3 个主要问题或子任务:

  1. 如何使用其他语言的库? 我只用 Python 试过这个。我使用 SIP 生成了一个 Python 组件,该组件已成功导入到 test.py 文件中,并从库中的一个类中调用了函数。我没有尝试过任何其他语言。

  2. 如何为其他语言的抽象类生成适当的声明或存根?由于插件必须实现这个类,我应该能够以某种方式生成与其他语言中的标头等效的内容,例如 Python 的 .py 文件、Java 的 .class 文件等。 我还没有尝试过,但我想有其他语言的生成器。

  3. 如何在插件中创建对象实例?如果我到了这一点,该类将在插件中实现。现在我需要调用返回已实现抽象类实例的函数,并获取指向它的指针。 根据我的研究,为了完成这项工作,我必须获得 Python 解释器、JVM 等的句柄,然后从那里与插件通信。

它看起来并不太复杂,但是当我开始研究时,即使是最简单的案例也需要大量的工作。我成功地只达到了第一点,而且只在 Python 中。这让我想知道我是否采取了正确的方法?你对此有什么想法。也许我不应该在我的库和抽象基类中使用 Qt,而只使用纯 C++。它可能会使事情变得更容易一些。或者也许我应该在我的库中只使用 C,并让插件返回一个 C 结构而不是一个类。我相信这会使事情变得更容易,因为调用图书馆将是一件微不足道的事情。而且我相信 C 结构的实现会比实现 C++ 类容易得多,甚至比实现使用 Qt 对象的 C++ 类更容易。

请为我指明正确的方向,并分享您在这方面的专业知识。另外,如果您知道任何有关该主题的书籍,我将非常乐意购买。或者一些处理这个的链接会做。

【问题讨论】:

  • 您要支持哪些语言?
  • 现在,我想支持 Java 和 Python。以后如果不是很复杂我会支持更多。

标签: java c++ python qt plugins


【解决方案1】:

C++ 会破坏其符号,并具有特殊的魔力来定义类,这有点像在标准 (C) 目标文件之上被破解。您不希望其他语言的文件能够理解这种魔力。所以我当然会按照你自己的建议,用纯 C 来做所有事情。

但是,这并不意味着您不能使用 C++。只有 interface 必须是 C,而不是实现。或者更严格地说,生成的目标文件不能使用其他语言不使用的特殊功能。

虽然插件可以链接到您的程序并因此使用其中的函数,但我个人发现在加载插件函数后调用插件函数更易读(因此可维护),传递一个函数指针数组,可以被插件使用。

  1. 每种语言都支持打开共享对象(SO 或 DLL)文件。使用它。

  2. 您的接口将由具有多个参数和返回类型的函数组成,这些函数可能在传递或检索它们方面有特殊需求。这可能有自动化系统,但我个人只会手动编写接口文件。最重要的是正确记录界面,这样人们就可以使用他们想要的任何语言,只要他们知道如何从他们的语言中加载目标文件。

  3. 不同的语言有非常不同的存储对象的方式。我建议让数据的创建者同时也是内存的所有者。因此,如果您的程序有一个带有构造函数的类(它包含在插件接口的 C 函数中),则该类是创建数据的类,并且您的程序而不是插件应该拥有它。这意味着插件需要在完成后通知您的程序,并且此时您的程序可以销毁它(当然,除非仍然需要它)。在支持它的语言中,例如 Python 和 C++,这可以在它们的接口对象被销毁时自动完成。 (我在这里假设插件将创建一个对象以与实际对象进行通信;该对象的行为类似于真实对象,但使用目标语言而不是 C。)

将任何库(例如 Qt)保留在界面之外。您可以允许诸如“将资源#x 放在屏幕上的这个位置”之类的功能,但不能允许“把这个 Qt 对象放在屏幕上的这个位置”之类的功能。原因是当你需要插件传递 Qt 对象时,他们需要理解 Qt,这使得编写插件变得更加困难。

如果插件完全受信任,您可以允许它们将(不透明的)指针传递给那些对象,但对于与使用其他数字类型没有任何不同的接口。只是不要求他们对对象做任何事情,除了在你的程序中调用函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    • 2020-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    相关资源
    最近更新 更多