提问人:andrewrk 提问时间:8/14/2008 最后编辑:sthandrewrk 更新时间:8/12/2010 访问量:3548
通过命令行向程序发送消息
Send messages to program through command line
问:
我有这个程序,我们称之为主机。主机可以做各种好事,但它需要能够在运行时通过命令行接受输入。这意味着它必须以某种方式发送其他进程数据,然后退出。例如,我需要能够做到这一点:
./Host --blahblah 3 6 3 5
这应该以某种方式最终调用主机中的一些函数,称为
handleBlahBlah(int x1, int y1, int x2, int y2){
//do some more sweet stuff
}
Host 是一个 C 程序,不需要支持多个实例。
这方面的一个例子是 Amarok 音乐播放器。随着 Amarok 的运行和播放,您可以键入“amarok --pause”,它将暂停音乐。
我需要能够在 Linux 或 Windows 中执行此操作。最好是 Linux。
实现这一点的最干净的方法是什么?
答:
所以,我可能错过了这里的重点,但通过耳聋,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 大师,所以我希望我没有犯任何错误。
编辑:好吧,他在追求别的东西,但在编辑问题之前还不是很清楚。不必跳到我的代表身上......
如果你在 Windows 上,我会告诉你使用一个隐藏的窗口来接收消息,但既然你使用了,我假设你想要一些基于 Unix 的东西。./
在这种情况下,我会使用命名的管道。Sun 有一个关于命名管道的教程,可能很有用。
该程序可能会创建管道并收听。您可以有一个单独的命令行脚本,该脚本将打开管道并将其命令行参数回显给它。
您可以修改程序以支持命令行发送,而不是使用单独的脚本。在这种情况下,你会做同样基本的事情。您的程序将查看其命令行参数,如果适用,请打开指向程序的“main”实例的管道,并发送参数。
评论
如果需要跨平台,您可能需要考虑让正在运行的实例侦听 TCP 端口,并让您从命令行启动的实例向该端口发送消息。
我建议使用 Unix 套接字或 D-Bus。如果您熟悉 Unix 套接字编程并且只需要一些操作,那么使用套接字可能会更快,而 D-Bus 可能会让您更容易专注于以熟悉的面向对象的方式实现功能。
看看 Beej 的 Unix IPC 指南,特别是关于 Unix 套接字的章节。
这里没有人说的是: “你不能从这里到达那里”。
命令行仅在调用程序时可用。
调用“fillinthename arguments ...”的示例要在 FillinTheName 运行后与 FillinTheName 进行通信,只能通过使用相互通信的两个程序实例来完成。
其他答案提出了实现沟通的方法。
类似 amarok 的程序需要检测另一个实例的存在 为了知道它必须扮演什么角色,主要角色 持久性消息接收者/服务器,或一次拍摄的次要角色 消息发件人。
编辑以实际显示单词 fillinthename。
我见过的一种技术是让你的程序仅仅成为你真实程序的“外壳”。例如,当您正常启动应用程序时(例如:),程序将分叉到代码的“主应用程序”部分。当您以暗示要向正在运行的实例发出信号的方式启动程序时(例如:),程序将分叉到代码的“消息发送器”部分。这就像将两个应用程序合二为一。另一个不使用的选项是制作一个纯粹的“消息发送器”应用程序,并将你的“主应用程序”作为一个单独的可执行文件(例如:),可以单独启动。Host
./Host
./Host --send-message restart
fork
Host
Host_core
Host
程序的“主应用程序”部分需要打开某种通信通道来接收消息,而“消息发送者”部分需要连接到该通道并使用它来发送消息。有几种不同的选项可用于在进程之间发送消息。一些更常见的方法是管道和插座。根据您的操作系统,您可能还有其他可用的选项;例如,QNX 有频道,BeOS/Haiku 有 BMessages。您还可以找到一个整齐地包装此功能的库,例如 lcm。
评论