Rust 段错误中的 XNextEvent()

XNextEvent() in Rust segfaults

几个月前,我开始用 C 语言和 Xlib 编写 X11 window 管理器,现在我正尝试用 Rust 重写它。 (毕竟,生锈是未来,对吧?)

这是来自 main.rs 的代码,出现段错误:

    // event loop
    loop {
        let mut event : *mut XEvent = 0 as *mut XEvent;
        unsafe {
            XNextEvent(DISPLAY, event);
            /*match (*event).type_ {
                CreateNotify => {
                    println!("sdfg");
                }
                _ => {
                    println!("sdfgsdfg");
                }
            }*/
        }
        println!("dsfgsdfg");
    }

使用 GDB,我能够将其缩小到不安全块内的 XNextEvent。我不太确定从那里去哪里,因为它正在调用一个函数 /use/lib/libX11.so.6 我无法列出该函数以查看它退出的位置。

在你询问不安全块之前,我不能将 Xlib 函数放在不安全块之外,因为它们是不安全函数,编译器会报错。

该项目在 crates.io 上使用 x11 crate。

您传递的是指向 NULL 的指针,而不是指向要由 XNextEvent 填充的局部变量的指针,就像您的 C 代码所做的那样:

XEvent *event = NULL;
XNextEvent(DISPLAY, event); //crash!

在 C 中,您可能正在做:

XEvent event;
XNextEvent(DISPLAY, &event);

但不幸的是你不能直接在 Rust 中这样做,因为你不能声明一个未初始化的变量:

let mut event: XEvent;
XNextEvent(DISPLAY, &mut event); //error: event is not initialized

如果 XEvent 实现了 Default 你可以默认初始化它,但我认为 it does not.

对于这些情况,您可以使用 MaybeUninit:

let event = unsafe {
    let mut event = MaybeUninit::uninit();
    XNextEvent(DISPLAY, event.as_mut_ptr());
    event.assume_init()
};