java - 如何用其他语言编写带有绑定(bind)的Qt插件系统?

标签 java c++ python qt plugins

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

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

至此我相信一切都清楚了,一个标准的插件接口(interface)。但是,有 3 个主要问题或子任务:

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

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

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

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

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

最佳答案

C++ 破坏了它的符号,并具有定义类的特殊魔力,这在某种程度上是在标准 (C) 目标文件之上进行的。您不希望来自其他语言的文件理解这种魔力。所以我当然会听从你自己的建议,用纯 C 做所有事情。

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

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

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

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

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

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

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

关于java - 如何用其他语言编写带有绑定(bind)的Qt插件系统?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11914614/

相关文章:

java - 如何连接Python聊天机器人和Java聊天室

java - 基本数组和循环 Java

java - Spring Data JPA 表连接创建运算符不存在错误

c++ - 为什么 boost::auto_cpu_timer 显示 > 100% 利用率?

java - 随机文本生成器

c++ - CreateFile() 因 GetLastError() = 5 而失败

c++ - 设置 3d 空间中对象的方向

python - 在 pySerial (Windows) 中查找特定的串行 COM 端口

python - 在列表中一次迭代两个项目的方法?

python - 这是使用 Django 将 CSV 文件的内容插入数据库的好习惯吗?