3

我正在用 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++ 类更容易。

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

4

1 回答 1

1

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

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

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

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

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

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

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

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

于 2012-11-26T10:45:45.540 回答