通过命令行向程序发送消息
我有这个程序,我们称它为主机。 Host可以完成各种出色的工作,但是它需要能够在运行时通过命令行接受输入。这意味着它必须以某种方式发送其其他过程数据然后退出。例如,我需要能够做到这一点:
./Host --blahblah 3 6 3 5
这应该以某种方式最终在Host中调用某些函数
handleBlahBlah(int x1, int y1, int x2, int y2){ //do some more sweet stuff }
主机是一个C程序,不需要支持多个实例。
例如Amarok音乐播放器。在运行和播放Amarok的情况下,我们可以键入" amarok --pause",它将暂停音乐。
我需要能够在Linux或者Windows中执行此操作。最好是Linux。
什么是实现此目的的最干净的方法?
解决方案
回答
因此,我可能在这里没有讲到重点,但是由于默默无言,C程序的main函数需要两个参数; argc,参数数量(至少一个)的计数,以及argv(或者arg向量),参数列表。我们可以只解析参数并调用正确的方法。
例如:
int main(int argc, *argv[]) { /*loop through each argument and take action*/ while (--argc > 0) { printf(%s%s, *++argv, (argc > 1) ? " " : ""); } }
将所有参数打印到屏幕。我不是C专家,所以我希望我没有犯任何错误。
编辑:好吧,他是在追求别的东西,但是在问题被编辑之前还不清楚。不必再关注我的代表了...
回答
如果我们使用的是Windows,我会告诉我们使用一个隐藏的窗口来接收消息,但是由于我们使用的是。/
,因此我假设我们想要基于Unix的东西。
在这种情况下,我将使用命名管道。 Sun提供了有关可能有用的命名管道的教程。
该程序可能会创建管道并进行监听。我们可能有一个单独的命令行脚本,该脚本将打开管道并仅向其回显其命令行参数。
我们可以修改程序以支持命令行发送,而不必使用单独的脚本。在这种情况下,我们将执行相同的基本操作。程序将查看它的命令行参数,如果适用,请打开通往该程序"主"实例的管道,然后将参数发送通过。
回答
如果需要跨平台,则可能要考虑使正在运行的实例在TCP端口上侦听,并让我们从命令行启动的实例将消息发送到该端口。
回答
我建议使用Unix套接字或者D-Bus。如果我们熟悉Unix套接字编程并且只需要一些操作,则使用套接字可能会更快,而D-Bus可能使集中精力以熟悉的面向对象的方式实现功能更加容易。
查看Beej的Unix IPC指南,特别是有关Unix套接字的章节。
回答
没有人在这里说的是:
"你不能从这里到达那里"。
命令行仅在调用程序时可用。
一旦运行fillinthename,调用" fillinthename参数..."与fillinthename进行通信的示例只能通过使用程序中相互通信的两个实例来完成。
其他答案则提出了实现沟通的方法。
一个类似amarok的程序需要检测另一个实例的存在
为了知道它必须扮演哪个角色,
持久的邮件接收者/服务器,或者次要角色
消息发件人。
编辑以使单词fillinthename实际显示。
回答
我见过的一种技术是让Host程序仅仅是真实程序的"外壳"。例如,当我们正常启动应用程序(例如:./ Host)时,该程序将插入代码的"主应用程序"部分。当我们以建议我们发信号通知正在运行的实例的方式启动程序时(例如:./Host --send-message restart
),该程序将进入代码的"消息发送者"部分。这就像是将两个应用程序合而为一。不使用fork的另一种选择是使Host纯粹是一个"消息发件人"应用程序,并将" main app"作为一个单独的可执行文件(例如Host_core),而Host可以单独启动。
程序的"主应用程序"部分将需要打开某种通信通道来接收消息,而"消息发送者"部分将需要连接到该通道并使用它来发送消息。有多个不同的选项可用于在进程之间发送消息。一些更常见的方法是管道和插座。根据操作系统,我们可能还可以使用其他选项。例如,QNX有通道,而BeOS / Haiku有BMessages。我们也许还可以找到一个完美地包装了此功能的库,例如lcm。