我正在开发一个交互式命令行工具。该工具显示一个提示,用户可以输入正在处理的命令和参数。执行命令后,会出现一个新的提示符,用户可以继续输入命令。当在cli模式下使用时,它与gdb调试器非常相似。该工具主要是用c++编写的,带有一些用于使用C库的包装器。
我想附加一个GUI (QT将是我的第一选择在这里)到我的工具,然而,我不知道如何做到这一点。如果您在internet上搜索,许多Unix开发人员更喜欢严格区分后端和前端。所以,我在考虑让GUI成为一个单独的可执行文件,它只使用我的命令行工具的功能。
实现这一点的最佳方法是什么?我应该使用管道或套接字进行进程间通信吗?例如,gdb使用TCP/IP,甚至允许GUI在与服务器不同的机器上运行!(但是,此功能不是必需的)。
如果使用某种IPC,通信应该如何工作?我是否应该使用ASCII接口(Unix编程的艺术倾向于此)?这样做的好处是,我的GUI只需要解析命令行工具的输出。我不需要改变我的工具,因为它没有太大的区别,如果工具写入套接字/管道或只是计数。如果是这样,我应该为IPC定义一个协议还是只是解析输入/输出?
另一种方法是直接将GUI集成到我的工具中,只产生一个可执行文件。Insight调试器就是这样做的。Insight不只是"使用"gdb,它在程序代码中有自己的gdb。这样我就不必编写解析器,我的GUI代码可以从我的"基础代码"调用函数。
或者我应该让我的命令行工具一个库,我可以链接到cli-或GUI前端?
解决我的问题的最好方法是什么?以上解决方案的优点/缺点是什么?你喜欢哪一种?正如您在问题中提到的,有几种方法可以构建两个软件。你要问自己三个问题:
- 两个代码段之间的关系是什么?
- 每个代码段在未来改变的可能性。
- 你的代码将如何部署
如果一个代码段是严格意义上的抽象层,在另一层之上(在你的例子中是CLI代码),核心CLI功能相对成熟和稳定,然而你发现GUI可能会经常改变,这可能建议你把CLI代码变成一个库,并让GUI代码包含库并"向下调用"CLI代码。另一方面,如果GUI代码将一堆软件捆绑在一起,而CLI代码则是一个更小,更孤立的模块,并且可能会以更高的频率更改(想想dvd播放器中的dvd),您可能会考虑将GUI作为导入不同"引擎"的框架,或者CLI模块。如果您希望这两个代码段具有并排的关系,例如,GUI可能发出HTTP请求来下载图像,而CLI代码可能在后台执行一些CPU密集型的数字运算,那么您可能希望探索将CLI和GUI作为单独的线程运行并相互通信。[根据两个代码段的紧密耦合程度,您可以探索单独的线程(无耦合),偶尔的消息传递(消息队列)到使用线程和细粒度锁(非常紧密耦合)。]
当将大型软件部署分解为更小的模块化单元时,分离的进程(带有可选的套接字接口以在不同的机器上运行)非常有用。只要你的代码仍然适合你的大脑,并且少于大约1万行代码,那么增加的代码复杂性和延迟是不合理的。
从你的描述听起来好像CLI代码是成熟的,而GUI将只是一个与CLI交互的shell。我也理解您打算将代码作为可执行文件发布。因此,我认为您的用例符合使您的CLI代码成为库,并编写与之接口的CLI shell和GUI shell。