Qt 通过管道到可执行 Linux 的双向通信

Posted

技术标签:

【中文标题】Qt 通过管道到可执行 Linux 的双向通信【英文标题】:Qt two way communication over pipe to executable Linux 【发布时间】:2012-03-14 09:00:11 【问题描述】:

我正在尝试编写一个 Qt GUI 应用程序,它可以与我制作的可执行文件进行通信,该文件处理来自 Qt GUI 应用程序的信息。

我可以理解并且已经能够实现单向 popen() 管道,它只允许我将信息发送到命令行实用程序,但输出只出现在 Qt 窗口底部的应用程序输出窗口中.

我一直在寻找互联网,我认为我必须使用两个管道与 fork() 和 exec()。

我的问题是,有谁知道这个或一些示例的好教程在哪里,或者任何人都可以向我展示实现这一目标的代码。

谢谢。

编辑::

我在这里有这段代码,但我不知道应该把它放在哪里。如果我将其放入我的 Qt GUI 应用程序,关闭管道会返回错误。

再次编辑::

这是我的 Qt GUI 按钮单击事件。但是我收到很多错误,说关闭的管道部件有问题。

mainwindow.cpp:85: error: no matching function for call to ‘MainWindow::close(int&)’

关闭的管道部件有什么问题?

void MainWindow::on_pushButton_clicked()

    QString stringURL = ui->lineEdit->text();

    ui->labelError->clear();
    if(stringURL.isEmpty() || stringURL.isNull()) 
        ui->labelError->setText("You have not entered a URL.");
        stringURL.clear();
        return;
    

    std::string cppString = stringURL.toStdString();
    const char* cString = cppString.c_str();

    char* output;

    //These arrays will hold the file id of each end of two pipes
    int fidOut[2];
    int fidIn[2];

    //Create two uni-directional pipes
    int p1 = pipe(fidOut);                  //populates the array fidOut with read/write fid
    int p2 = pipe(fidIn);                   //populates the array fidIn  with read/write fid
    if ((p1 == -1) || (p2 == -1)) 
        printf("Error\n");
        return 0;
    

    //To make this more readable - I'm going to copy each fileid
    //into a semantically more meaningful name
    int parentRead  = fidIn[0];
    int parentWrite = fidOut[1];
    int childRead   = fidOut[0];
    int childWrite  = fidIn[1];

    //////////////////////////
    //Fork into two processes/
    //////////////////////////
    pid_t processId = fork();

    //Which process am I?
    if (processId == 0) 
        /////////////////////////////////////////////////
        //CHILD PROCESS - inherits file id's from parent/
        /////////////////////////////////////////////////
        close(parentRead);      //Don't need these
        close(parentWrite);     //

        //Map stdin and stdout to pipes
        dup2(childRead,  STDIN_FILENO);
        dup2(childWrite, STDOUT_FILENO);

        //Exec - turn child into sort (and inherit file id's)
        execlp("htmlstrip", "htmlstrip", "-n", NULL);

     else 
        /////////////////
        //PARENT PROCESS/
        /////////////////
        close(childRead);       //Don't need this
        close(childWrite);      //

        //Write data to child process
        char strMessage[] = cString;
        write(parentWrite, strMessage, strlen(strMessage));
        close(parentWrite);     //this will send an EOF and prompt sort to run

        //Read data back from child
        char charIn;
        while ( read(parentRead, &charIn, 1) > 0 ) 
            output = output + (charIn);
        
        close(parentRead);      //This will prompt the child process to quit
    

    return 0;

【问题讨论】:

【参考方案1】:

对于 IPC b/w Qt 应用程序,您可以选择共享内存或本地套接字/服务器。

查看这里的共享内存示例:

http://www.developer.nokia.com/info/sw.nokia.com/id/ad9f51ff-c18f-4bd7-8bb8-cd9681704783/Qt_QSharedMemory_Example_v1_2_en.zip.html

【讨论】:

以上是关于Qt 通过管道到可执行 Linux 的双向通信的主要内容,如果未能解决你的问题,请参考以下文章

双向命名管道问题

Qt使用QProcess进程间双向通信(linux和win系统)

c#命名管道双向通信

管道双向通信

独立程序的多对一双向通信

在 C 中使用管道在父子之间创建双向通信