简体   繁体   English

在 C 中,有没有办法将一个程序的返回值传递给另一个程序?

[英]In C, is there a way to pass a return value of one program to another program?

I have 2 basic questions since I'm new at C:因为我是 C 新手,所以我有 2 个基本问题:

  1. How to go about passing the return value of a C program to another program?如何将 C 程序的返回值传递给另一个程序? prog1 will list out items (number of items can be varied each time of execution) and I'd like to store and pass ONLY the last item value to another prog2 for different purpose. prog1 将列出项目(项目数量可以在每次执行时改变),我只想存储最后一个项目值并将其传递给另一个 prog2 以用于不同的目的。 Basically the output of prog1 is below and I'd like to extract the last item on the list which is /dev/hidraw2 for the prog2.基本上prog1的输出在下面,我想提取列表中的最后一项,即prog2的/dev/hidraw2。 Prog2 is currently using hardcoded value and I'd like to make it more dynamic. Prog2 目前正在使用硬编码值,我想让它更加动态。

prog1 output: prog1 输出:

/dev/hidraw0
/dev/hidraw1
/dev/hidraw2

prog1 code can be found here: prog1 代码可以在这里找到:

https://pastebin.pl/view/379db296 https://pastebin.pl/view/379db296

prog2 code snippet is below: prog2 代码片段如下:

/* C */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

const char *bus_str(int bus);

int main(int argc, char **argv)
{
        int fd;
        int i, res, desc_size = 0;
        char buf[256];
        struct hidraw_report_descriptor rpt_desc;
        struct hidraw_devinfo info;
        char *device = "/dev/hidraw2";   /*** replace hardcoded value here dynamically ***/

        if (argc > 1)
                device = argv[1];

        /* Open the Device with non-blocking reads. In real life,
           don't use a hard coded path; use libudev instead. */
        fd = open(device, O_RDWR);
  1. If question 1 above is resolved, can I incorporate prog1 into prog2 directly even though they have different compilation parameters?如果上面的问题 1 解决了,即使它们具有不同的编译参数,我是否可以直接将 prog1 合并到 prog2 中? Do you forsee any issue there?你预见到那里有什么问题吗?

prog1 compile command: prog1 编译命令:
gcc -Wall -g -o prog1 prog1.c -ludev gcc -Wall -g -o prog1 prog1.c -ludev

prog2 compile command: prog2 编译命令:
gcc prog2 prog2.c gcc prog2 prog2.c

One way, and there are many, is to use fork.一种方法,并且有很多,是使用 fork。 fork() is a little unlike other C function calls. fork()与其他 C 函数调用有点不同。 When you call it, you get an extra copy of the running process.当你调用它时,你会得到一个正在运行的进程的额外副本。 You can then compare the return value to determine which process is the parent and which process is the child.然后,您可以比较返回值以确定哪个进程是父进程,哪个进程是子进程。

The overall logic would then look a little like:整个逻辑看起来有点像:

while (looping) {
   char device[] = (set to the desired value);
   int childPID = fork();
   if (childPID == 0) {
       /* this is the child */
       doWhatever(device);
       exit(0);
   } else {
       /* this is the parent */
       /* let's wait on the child to complete */
       wait();           
   }

Now this example is very simple.现在这个例子非常简单。 There are many other considerations;还有很多其他的考虑; but this approach avoids other more complex ways to pass information between processes.但是这种方法避免了在进程之间传递信息的其他更复杂的方法。 Basically the child is created as a copy of the program at the moment in time that fork() is called, so the contents of device will be shared between the two processes.基本上,在调用fork()时,子进程被创建为程序的副本,因此device的内容将在两个进程之间共享。

Some of the problems to watch out for is that children need to report their exit codes to their parent processes.需要注意的一些问题是子进程需要向父进程报告他们的退出代码。 So if you don't want to have one process running at a time, you'll need a more complex way to wait() on the children.因此,如果您不想一次运行一个进程,则需要一种更复杂的方法来wait()子进程。

If you kill the parent process in this example, the children will also be killed.如果在本例中杀死父进程,子进程也将被杀死。 That may or may not be what you desire.这可能是也可能不是你想要的。

Other approaches (some much better than others):其他方法(有些比其他方法好得多):

  1. Using IPC to create a producer / consumer pattern based on shared memory and semaphores (to control who's writing to the shared memory, so reading processes don't read partially written entries or remove items partially creating problems with writers.使用 IPC 创建基于共享内存和信号量的生产者/消费者模式(以控制谁写入共享内存,因此读取过程不会读取部分写入的条目或删除部分创建问题的项目。
  2. Using the above approach (fork) but creating an unnamed pipe in the patern that the child then reads from.使用上述方法(fork),但在子进程读取的模式中创建一个未命名的管道。 This can permit the child to process more than one request.这可以允许孩子处理多个请求。
  3. Using a named pipe (a very special kind of file) that exists independently of the two programs.使用独立于两个程序存在的命名管道(一种非常特殊的文件)。 This allows independent launching of the child(ren).这允许独立启动孩子。
  4. Using a regular file, written by the producer and read by the consumer(s).使用由生产者编写并由消费者读取的常规文件。 This will require some sort of signalling for when the file is safe to write to (so consumers don't get bad reads) and when the file is safe to read / shorten (so the writers don't corrupt the file).这将需要某种信号,指示文件何时可以安全写入(因此消费者不会读取错误)以及文件何时可以安全读取/缩短(因此写入者不会损坏文件)。

I'm sure there are many other approaches;我相信还有很多其他方法; but, when you have two programs cooperating to solve a problem, you start to encounter a lot of issues that you don't normally have when only considering one program solving the problem.但是,当您有两个程序合作解决一个问题时,您会开始遇到很多问题,而这些问题通常在只考虑一个程序解决问题时不会遇到。

Some of the things to consider:需要考虑的一些事项:

  1. The communication is reliable - files, sockets, networks, etc. all sometimes fail.通信是可靠的——文件、套接字、网络等有时都会失败。 You need to verify your sends were sent and provide some means for knowing your data is not corrupt due to the transport.您需要验证您的发送是否已发送,并提供一些方法来了解您的数据没有因传输而损坏。

  2. The act of communicating requires time - you will need to handle delays in both the packaging, insertion, retrieval, and unpackaging of the transmission;通信行为需要时间——您需要处理传输的打包、插入、检索和拆包过程中的延迟; and, often those delays can change dramatically for each message.并且,对于每条消息,这些延迟通常会发生巨大变化。

  3. The number of messages that can be handled is finite - transmission requires time, and time implies a rate of transmission.可以处理的消息数量是有限的——传输需要时间,时间意味着传输速率。 Since there is a rate involved, you cannot design a working program that ignores the limits of the communication path.由于涉及到速率,您不能设计一个忽略通信路径限制的工作程序。

  4. The message can be corrupted or eavesdropped - While we like to think that computers never make errors, when communicating errors in the data occur more frquently.消息可能被破坏或窃听 - 虽然我们认为计算机永远不会出错,但当数据中的通信错误更频繁地发生时。 These can be due to lots of reasons (people testing sockets with telnet, electrical interference with networks, pipe files being removed, etc.) In addition, the data itself is more easily read by others, which is a problem for some programs.这可能是由于很多原因(人们使用 telnet 测试套接字、对网络的电气干扰、管道文件被删除等)此外,数据本身更容易被其他人读取,这对某些程序来说是一个问题。

  5. The way the transmission occurs changes - Even if you are using files instead of networks to transmit information, administrators can move files and insert symlinks.传输方式发生变化 - 即使您使用文件而不是网络来传输信息,管理员也可以移动文件并插入符号链接。 Networks may send every bit of information through a different path.网络可以通过不同的路径发送每一位信息。 Don't assume a static path.不要假设静态路径。

  6. You can't provide instructions to avoid critical issues - No computer has only one administrator, even if it is your own personal computer.您无法提供避免关键问题的说明 - 没有计算机只有一个管理员,即使它是您自己的个人计算机。 Automated systems and subroutines, as well as other people, ensure that you'll never be able to provide instructions on how to work around issues to all the right people.自动化系统和子程序以及其他人确保您永远无法向所有合适的人提供有关如何解决问题的说明。 Write your solutions avoiding a need for workarounds that are implemented by people following a custom "required" procedure.编写您的解决方案,避免需要由遵循自定义“必需”程序的人员实施的变通方法。

  7. Moving data is not free - it costs time, electricity, RAM, CPU, and possibly disk or network.移动数据不是免费的——它需要时间、电力、RAM、CPU,可能还有磁盘或网络。 These costs can grow (if not managed) to prevent your program from functioning, even if all other parts of the solution are correct.即使解决方案的所有其他部分都是正确的,这些成本也会增加(如果不加以管理)以阻止您的程序运行。

  8. Transportation of data is often not homogenous - Once you commit to a way of communicating information, odds are that it will not be easy to replace it with another way easily.数据的传输通常不是同质的 - 一旦您承诺采用一种信息交流方式,很可能不容易用另一种方式轻松替换它。 Many of the solutions provide additional features that aren't present in other approaches, and even if you decide on "network only" transport, the difference between networks may make your solution less generic that you might think.许多解决方案提供了其他方法中不存在的附加功能,即使您决定使用“仅网络”传输,网络之间的差异也可能使您的解决方案不像您想象的那样通用。

Armed with these realizations, it will be much easier for you to create a solution that works, and doesn't fall apart when some tiny detail changes.有了这些认识,您就可以更轻松地创建一个有效的解决方案,并且在一些微小的细节发生变化时不会崩溃。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM