GTKmm +管道()不工作

发布于 2025-01-01 00:18:36 字数 2350 浏览 1 评论 0原文

我有这段代码:

#include <gtkmm.h>
#include <unistd.h>


void send_msg(Gtk::Entry* entry, int* fd);
Glib::ustring* receive_msg(int* fd);
bool handle_msg(Gtk::Label* lbl, int* fd);




int main()
{
    pid_t pid = fork();

    int fd[2];
    pipe(fd);

    Gtk::Main gtkmain;
    Gtk::Window* win;
    Glib::RefPtr<Gtk::Builder> builder;

    if (pid > 0)
    {
        close(fd[1]);

        builder = Gtk::Builder::create_from_file("parent.glade");
        builder->get_widget("parentwin", win);

        Gtk::Label* lbl;
        builder->get_widget("label", lbl);
        sigc::slot<bool> timer = sigc::bind(sigc::ptr_fun(&handle_msg), lbl, fd);
        Glib::signal_timeout().connect(timer, 1000);
    }
    else if (pid == 0)
    {
        close(fd[0]);

        builder = Gtk::Builder::create_from_file("child.glade");
        builder->get_widget("childwin", win);

        Gtk::Button* send;
        Gtk::Entry* txt;
        builder->get_widget("send", send);
        builder->get_widget("msg", txt);
        send->signal_clicked().connect(sigc::bind(sigc::ptr_fun(&send_msg), txt, fd));
    }

    Gtk::Main::run(*win);

    return EXIT_SUCCESS;
}







void send_msg(Gtk::Entry* entry, int* fd)
{
    Glib::ustring msg = entry->get_text();
    const char* c_msg = msg.c_str();

    int i = 0;
    char* c = new char(0);

    while (*c = c_msg[i++])
    {
        write(fd[1], c, 1);
    }
}



Glib::ustring* receive_msg(int* fd)
{
    Glib::ustring* msg = new Glib::ustring;
    char* c = new char(0);

    do
    {
        read(fd[0], c, 1);
        msg->append(c);
    } while (*c);

    return msg;
}



bool handle_msg(Gtk::Label* lbl, int* fd)
{
    Glib::ustring* msg;
    msg = receive_msg(fd);
    lbl->set_text(*msg);
    // delete msg;
    return true;
}

它的目的是这样的: 整个程序的工作原理与聊天程序类似,只是不是为此目的。 child 进程会打开一个窗口,其中包含 Entry 和 Button,使用使用 write() 函数的低级代码发送 Entry 的内容,并且父级会打开一个窗口,其中只有一个标签,用于显示使用 read() 在低级别接收到的数据。

我追求的确切功能无需 gtkmm 即可实现,但即使我在 下的 gtkmm 部分之前编写 read()write() 代码close()来测试读/写的功能作​​为绕过函数调用的测试,仍然不行。

我能想到的唯一可能性是 unistd.hgtkmm.h 之间不兼容。

(而且我也知道代码在某种程度上是一堆脏东西,但它是一种实践,忘记这一点!;-))

非常感谢您的帮助:-)

I have this code:

#include <gtkmm.h>
#include <unistd.h>


void send_msg(Gtk::Entry* entry, int* fd);
Glib::ustring* receive_msg(int* fd);
bool handle_msg(Gtk::Label* lbl, int* fd);




int main()
{
    pid_t pid = fork();

    int fd[2];
    pipe(fd);

    Gtk::Main gtkmain;
    Gtk::Window* win;
    Glib::RefPtr<Gtk::Builder> builder;

    if (pid > 0)
    {
        close(fd[1]);

        builder = Gtk::Builder::create_from_file("parent.glade");
        builder->get_widget("parentwin", win);

        Gtk::Label* lbl;
        builder->get_widget("label", lbl);
        sigc::slot<bool> timer = sigc::bind(sigc::ptr_fun(&handle_msg), lbl, fd);
        Glib::signal_timeout().connect(timer, 1000);
    }
    else if (pid == 0)
    {
        close(fd[0]);

        builder = Gtk::Builder::create_from_file("child.glade");
        builder->get_widget("childwin", win);

        Gtk::Button* send;
        Gtk::Entry* txt;
        builder->get_widget("send", send);
        builder->get_widget("msg", txt);
        send->signal_clicked().connect(sigc::bind(sigc::ptr_fun(&send_msg), txt, fd));
    }

    Gtk::Main::run(*win);

    return EXIT_SUCCESS;
}







void send_msg(Gtk::Entry* entry, int* fd)
{
    Glib::ustring msg = entry->get_text();
    const char* c_msg = msg.c_str();

    int i = 0;
    char* c = new char(0);

    while (*c = c_msg[i++])
    {
        write(fd[1], c, 1);
    }
}



Glib::ustring* receive_msg(int* fd)
{
    Glib::ustring* msg = new Glib::ustring;
    char* c = new char(0);

    do
    {
        read(fd[0], c, 1);
        msg->append(c);
    } while (*c);

    return msg;
}



bool handle_msg(Gtk::Label* lbl, int* fd)
{
    Glib::ustring* msg;
    msg = receive_msg(fd);
    lbl->set_text(*msg);
    // delete msg;
    return true;
}

and it's purpose is this:
The whole program works similar to a chat program, just not intended for that. The child process brings up a window with an Entry and a Button in it, to send the contents of Entry using a low level code that uses write() function, and the parent brings up a window with just a Label in it to display the data received at low level with read().

The exact functionality that I'm after I could achieve without gtkmm, but even when I write the read() and write() codes right before gtkmm parts under close() to test the functionality of read/write as a test to bypass function calls, it still won't work.

The only possibility I can think of, is an incompatibility between unistd.h and gtkmm.h.

(and also I know the code is a bunch of dirt in writing, to some extent, but its a practice, forget that! ;-) )

Thanks so much for your helps :-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

初见你 2025-01-08 00:18:36

您的管道管理代码是错误的。您应该在fork()之前pipe(),以确保两个文件描述符都继承到子进程中。阅读这些函数的文档。

这里是一个相当密集的Unix编程教程,可以清楚地看到pipe () 或多或少是启动子进程之前进行的第一个调用。

Your pipe-management code is wrong. You're supposed to pipe() before you fork(), to make sure both file descriptors are inherited into the child process. Read up on the documentation of these functions.

Here is a quite dense tutorial on Unix programming, it's clearly visible that pipe() is more or less the first call made, before launching the child process.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文