GTKmm +管道()不工作
我有这段代码:
#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.h
和 gtkmm.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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的管道管理代码是错误的。您应该在
fork()
之前pipe()
,以确保两个文件描述符都继承到子进程中。阅读这些函数的文档。这里是一个相当密集的Unix编程教程,可以清楚地看到
pipe ()
或多或少是启动子进程之前进行的第一个调用。Your pipe-management code is wrong. You're supposed to
pipe()
before youfork()
, 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.