通过命令行向程序发送消息

时间:2008-08-13 22:40:58

标签: c architecture command-line io

我有这个程序,我们称之为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。

实施此最简洁的方法是什么?

6 个答案:

答案 0 :(得分:8)

如果您使用的是Windows,我会告诉您使用隐藏窗口来接收消息,但是由于您使用了./,我认为您需要基于Unix的东西。

在这种情况下,我会选择named pipe。 Sun有一个tutorial关于可能有用的命名管道。

程序可能会创建管道并监听。您可以使用单独的命令行脚本来打开管道,并将其命令行参数回显给它。

可以修改您的程序以支持命令行发送,而不是使用单独的脚本。在这种情况下你会做同样的基本事情。您的程序将查看它的命令行参数,如果适用,打开管道到程序的“main”实例,并发送参数。

答案 1 :(得分:5)

如果它需要跨平台,您可能需要考虑让正在运行的实例侦听TCP端口,并让您从命令行启动的实例向该端口发送消息。

答案 2 :(得分:4)

我建议使用Unix socketD-Bus。如果您熟悉Unix套接字编程并且只需要一些操作,那么使用套接字可能会更快,而D-Bus可能会更容易专注于以熟悉的面向对象的方式实现功能。

请查看Beej's Guide to Unix IPC,尤其是关于Unix sockets的章节。

答案 3 :(得分:1)

这里没有人说过这个: “你不能从这里到达那里”。

命令行仅在调用程序时可用。

一旦 fillinthename 正在运行,调用“ fillinthename 参数...”与 fillinthename 进行通信的示例只能通过使用两个来完成程序实例相互通信。

其他答案提出了实现沟通的方法。

amarok 之类的程序需要检测另一个实例的存在 本身,以了解它必须扮演的角色,主要角色 持久性消息接收者/服务器,或者一次性的次要角色 邮件发件人。

编辑以实际显示fillinthename这个词。

答案 4 :(得分:0)

我看到的一种技巧是让你的Host程序只是你真实程序的“shell”。例如,当您正常启动应用程序时(例如:./Host),程序将分叉到代码的“主应用程序”部分。当您以一种暗示您想要发送正在运行的实例的方式启动程序时(例如:./Host --send-message restart),程序将分叉到代码的“消息发送方”部分。这就像在一个中有两个应用程序。另一个不使用fork的选项是将Host纯粹设为“消息发送者”应用,并将您的“主应用”作为单独的可执行文件(例如:Host_core){{{ 1}}可以单独启动。

程序的“主应用程序”部分需要打开某种通信通道来接收消息,“消息发送者”部分需要连接到该通道并使用它来发送消息。有几种不同的选项可用于在进程之间发送消息。一些更常见的方法是pipessockets。根据您的操作系统,您可以选择其他选项;例如,QNX有channels,BeOS / Haiku有BMessages。您也可以找到一个整齐地包含此功能的库,例如lcm

答案 5 :(得分:-2)

所以,我可能会忽略这一点,但是通过嘲笑C程序的主函数有两个参数; argc,参数数量的计数(至少一个)和argv(或arg vector),参数列表。您可以解析参数并调用正确的方法。 例如:

 int main(int argc, *argv[])
 {
     /*loop through each argument and take action*/
      while (--argc > 0)
      {
           printf(%s%s, *++argv, (argc > 1) ? " " : "");
      }
 } 

会将所有参数打印到屏幕上。我不是C大师,所以我希望我没有犯过任何错误。

编辑:好的,他是在追求其他东西,但在编辑问题之前并不是很清楚。不必跳我的代表...