将mmap存储的整数传递给GTK

问题描述 投票:1回答:1

编辑

这个问题最终是两个问题合而为一。但是,我不能删除这个问题。有关指针的原始问题的范围已由@David Ranieri解决。 mmap / fork / gtk问题将是一个新问题的范围,在这里不再解决。


我想打印我存储在GTK窗口中的内存中的值。该整数必须使用mmap存储,才能在代码中其他位置的派生过程中保留。如果没有获取SegFault,我无法从GTK引用此内存映射地址。我在这里做错什么了吗?有没有更好的方法?

我当前的策略:

  • intmmap处保留*VAL的内存
  • 叉过程,一半修改VAL,另一半运行GTK
  • *VAL传递到用户数据插槽中的应用程序
  • 现在localval中的用户数据称为activate()
  • 通过从localval转换为gpointer在地址int上打印值。

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));

但是编译器认为我想使用作为比较器。

c gtk3 mmap
1个回答
1
投票

您正在将已取消引用的指针(值)传递给需要指针的函数:

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 **)

而且gpointervoid *的别名,使用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); 
© www.soinside.com 2019 - 2024. All rights reserved.