将使用 mmap 存储的整数传递给 GTK
Passing an integer stored with mmap to GTK
编辑
这道题最终将两个问题合二为一。但是,我不能删除这个问题。 @David Ranieri 解决了有关指针的原始问题的范围。 mmap/fork/gtk 问题将是新问题的范围,不会在这里解决。
我想打印存储在 GTK 内存中的值 window。整数必须使用 mmap
存储,以便在代码的其他地方的分叉期间保留。如果没有得到 SegFault,我无法从 GTK 引用这个内存映射地址。我在这里做错了什么吗?有没有更好的方法?
我目前的策略:
- 在
*VAL
为 mmap
的 int
保留内存
- fork进程,一半修改
VAL
另一半运行s GTK
- 将
*VAL
传递给用户数据槽中的应用程序
- 用户数据现在在
activate()
中称为 localval
- 通过将
gpointer
转换为 int
来打印地址 localval
处的值。
MWE(这会导致段错误,运行 风险自负):
/*
* MMAP Variable SegFault
*/
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <gtk/gtk.h>
static void activate (GtkApplication *app, gpointer *localval) {
GtkWidget *window;
// Button Containers
GtkWidget *button_box_quit;
// Buttons
GtkWidget *exit_button;
// Text
GtkWidget *text_status;
// Define Window, dynamic size for screen.
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "test");
gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
// Define Button Boxes.
button_box_quit = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
// Define Exit Button, put it in a box, put box in window
exit_button = gtk_button_new_with_label ("Exit");
gtk_container_add(GTK_CONTAINER (button_box_quit), exit_button);
gtk_container_add(GTK_CONTAINER (window), button_box_quit);
// Connect signals to buttons
g_signal_connect_swapped (exit_button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
// Define text status
char msg[32]={0};
// The "print" line
g_snprintf(msg, sizeof msg, "val: %d\n", GPOINTER_TO_INT(*localval));
text_status = gtk_label_new(msg);
gtk_container_add(GTK_CONTAINER (button_box_quit), text_status);
//Activate!
gtk_widget_show_all (window);
}
int main (int argc, char **argv) {
GtkApplication *app;
int status;
int *VAL = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
int *ABORT = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
int pid = fork();
if (pid == 0) {
while(!*ABORT) {
printf("%d\n", *VAL);
*VAL = *VAL + 1;
usleep(1000000);
}
exit(0);
} else {
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
// The passing line
g_signal_connect (app, "activate", G_CALLBACK (activate), (gpointer *)*VAL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
*ABORT = 1;
}
*ABORT = 1;
return status;
}
在此代码的非工作替代方案中,我尝试将打印行更改为:
g_snprintf(msg, sizeof msg, "val: %d\n", &GPOINTER_TO_INT(*localval));
但是编译器认为我想使用 & 作为比较器。
您正在将取消引用的指针(值)传递给需要指针的函数:
int *VAL = ...;
...
g_signal_connect (app, "activate", G_CALLBACK (activate), (gpointer *)*VAL);
切换到
g_signal_connect (app, "activate", G_CALLBACK (activate), VAL); // Do not use a wrong cast (void **)
此外,gpointer
是 void *
的别名,使用 gpointer *data
你会得到一个 void **data
,不是你想要的,所以
static void activate (GtkApplication *app, gpointer *localval) {
应该是
static void activate (GtkApplication *app, gpointer localval) { // without *
最后,打印指针的值使用
g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)localval);
编辑
这道题最终将两个问题合二为一。但是,我不能删除这个问题。 @David Ranieri 解决了有关指针的原始问题的范围。 mmap/fork/gtk 问题将是新问题的范围,不会在这里解决。
我想打印存储在 GTK 内存中的值 window。整数必须使用 mmap
存储,以便在代码的其他地方的分叉期间保留。如果没有得到 SegFault,我无法从 GTK 引用这个内存映射地址。我在这里做错了什么吗?有没有更好的方法?
我目前的策略:
- 在
*VAL
为 - fork进程,一半修改
VAL
另一半运行s GTK - 将
*VAL
传递给用户数据槽中的应用程序 - 用户数据现在在
activate()
中称为 - 通过将
gpointer
转换为int
来打印地址localval
处的值。
mmap
的 int
保留内存
localval
MWE(这会导致段错误,运行 风险自负):
/*
* MMAP Variable SegFault
*/
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <gtk/gtk.h>
static void activate (GtkApplication *app, gpointer *localval) {
GtkWidget *window;
// Button Containers
GtkWidget *button_box_quit;
// Buttons
GtkWidget *exit_button;
// Text
GtkWidget *text_status;
// Define Window, dynamic size for screen.
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "test");
gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
// Define Button Boxes.
button_box_quit = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
// Define Exit Button, put it in a box, put box in window
exit_button = gtk_button_new_with_label ("Exit");
gtk_container_add(GTK_CONTAINER (button_box_quit), exit_button);
gtk_container_add(GTK_CONTAINER (window), button_box_quit);
// Connect signals to buttons
g_signal_connect_swapped (exit_button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
// Define text status
char msg[32]={0};
// The "print" line
g_snprintf(msg, sizeof msg, "val: %d\n", GPOINTER_TO_INT(*localval));
text_status = gtk_label_new(msg);
gtk_container_add(GTK_CONTAINER (button_box_quit), text_status);
//Activate!
gtk_widget_show_all (window);
}
int main (int argc, char **argv) {
GtkApplication *app;
int status;
int *VAL = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
int *ABORT = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
int pid = fork();
if (pid == 0) {
while(!*ABORT) {
printf("%d\n", *VAL);
*VAL = *VAL + 1;
usleep(1000000);
}
exit(0);
} else {
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
// The passing line
g_signal_connect (app, "activate", G_CALLBACK (activate), (gpointer *)*VAL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
*ABORT = 1;
}
*ABORT = 1;
return status;
}
在此代码的非工作替代方案中,我尝试将打印行更改为:
g_snprintf(msg, sizeof msg, "val: %d\n", &GPOINTER_TO_INT(*localval));
但是编译器认为我想使用 & 作为比较器。
您正在将取消引用的指针(值)传递给需要指针的函数:
int *VAL = ...;
...
g_signal_connect (app, "activate", G_CALLBACK (activate), (gpointer *)*VAL);
切换到
g_signal_connect (app, "activate", G_CALLBACK (activate), VAL); // Do not use a wrong cast (void **)
此外,gpointer
是 void *
的别名,使用 gpointer *data
你会得到一个 void **data
,不是你想要的,所以
static void activate (GtkApplication *app, gpointer *localval) {
应该是
static void activate (GtkApplication *app, gpointer localval) { // without *
最后,打印指针的值使用
g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)localval);