gpt4 book ai didi

rust - 为什么 Rust 找不到 wl_display_get_registry?

转载 作者:行者123 更新时间:2023-11-29 07:58:02 26 4
gpt4 key购买 nike

在编写使用 Wayland 客户端 API 的代码时,Rust 似乎无法找到 wl_display_get_registry 符号。该文件的 objdump 也无法找到该符号。但是,用 GCC 编译的 C 程序能够找到该符号。

为什么C程序能找到符号,而Rust却不能?如何修复 Rust 程序以找到符号?

操作系统:Ubuntu 18.04 LTS

使用rust

构建

rustc -o wayland main.rs

输出

error: linking with `cc` failed: exit code: 1
|
= note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "wayland.main0.rcgu.o" "wayland.main1.rcgu.o" "wayland.main2.rcgu.o" "wayland.main3.rcgu.o" "wayland.main4.rcgu.o" "-o" "wayland" "wayland.crate.allocator.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "-L" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-l" "wayland-client" "-Wl,--start-group" "-Wl,-Bstatic" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-2da986ecbb2c5327.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-57f46841c9a9f4ee.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc_jemalloc-23263fe5893322f6.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-6ed5262c9a0a3e5a.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc_system-99c162b689d43349.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-cd415b85dd267875.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-3876ac10aa96a1e3.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_unicode-598b0e9aca382e9a.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-4eabb2b1c31071b8.rlib" "-Wl,--end-group" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-d7a656735ceeae9e.rlib" "-Wl,-Bdynamic" "-l" "dl" "-l" "rt" "-l" "pthread" "-l" "pthread" "-l" "gcc_s" "-l" "c" "-l" "m" "-l" "rt" "-l" "pthread" "-l" "util" "-l" "util"
= note: wayland.main3.rcgu.o: In function `main::main':
main3-317d481089b8c8fe83113de504472633.rs:(.text._ZN4main4main17h52709beaa06fe157E+0x109): undefined reference to `wl_display_get_registry'
collect2: error: ld returned 1 exit status

代码

pub enum WLDisplay {}
pub enum WLRegistry {}

#[link(name = "wayland-client")]
extern "C" {
pub fn wl_display_connect(name: *const ::std::os::raw::c_char) -> *mut WLDisplay;
pub fn wl_display_disconnect(display: *mut WLDisplay) -> ();

pub fn wl_display_get_registry(display: *mut WLDisplay) -> *mut WLRegistry;
}

fn main() {
let display: *mut WLDisplay;
let registry: *mut WLRegistry;

unsafe {
display = wl_display_connect(::std::ptr::null());
if display.is_null() == true {
eprintln!("Unable to connect to the Wayland display server.");
return;
}
println!("Connected to Wayland display server.");

println!("Retrieving the registry from the Wayland display.");
registry = wl_display_get_registry(display);
if registry.is_null() == true {
eprintln!("Unable to retrieve registry.");
} else {
println!("Registry retrieved.");
}

wl_display_disconnect(display);
println!("Disconnected from Wayland display server.");
}
}

C

构建

gcc -o wayland -lwayland-client main.c

输出

Connected to Wayland display server.
Retrieving the registry from the Wayland display.
Registry retrieved.
Disconnected from Wayland display server.

代码

#include <stdio.h>
#include <wayland-client.h>


int main()
{
struct wl_display *display;
struct wl_registry *registry;

display = wl_display_connect(NULL);
if (display == NULL)
{
fprintf(stderr, "Unable to connect to the Wayland display server.\n");
return 1;
}
fprintf(stdout, "Connected to Wayland display server.\n");

fprintf(stdout, "Retrieving the registry from the Wayland display.\n");
registry = wl_display_get_registry(display);
if (registry == NULL)
{
fprintf(stderr, "Unable to retrieve registry.\n");
}
else
{
fprintf(stdout, "Registry retrieved.\n");
}

wl_display_disconnect(display);
fprintf(stdout, "Disconnected from Wayland display server.\n");

return 0;
}

对象转储

命令

objdump -TC /usr/lib/x86_64-linux-gnu/libwayland-client.so | grep "wl_display*"

输出

0000000000005f60 g DF .text 0000000000000275  Base wl_display_connect
0000000000006960 g DF .text 0000000000000078 Base wl_display_flush
0000000000006a90 g DF .text 000000000000000c Base wl_display_dispatch
00000000000067b0 g DF .text 0000000000000042 Base wl_display_cancel_read
00000000000068c0 g DF .text 000000000000000c Base wl_display_dispatch_pending
0000000000006800 g DF .text 00000000000000bf Base wl_display_dispatch_queue_pending
00000000000061e0 g DF .text 0000000000000057 Base wl_display_disconnect
0000000000006be0 g DF .text 00000000000000fc Base wl_display_roundtrip_queue
00000000000068d0 g DF .text 000000000000002c Base wl_display_get_error
0000000000005610 g DF .text 0000000000000031 Base wl_display_create_queue
0000000000006740 g DF .text 0000000000000052 Base wl_display_prepare_read_queue
0000000000006900 g DF .text 0000000000000051 Base wl_display_get_protocol_error
0000000000005dc0 g DF .text 0000000000000194 Base wl_display_connect_to_fd
00000000000069e0 g DF .text 00000000000000ac Base wl_display_dispatch_queue
0000000000006ce0 g DF .text 000000000000000c Base wl_display_roundtrip
0000000000006250 g DF .text 00000000000004f0 Base wl_display_read_events
0000000000006240 g DF .text 0000000000000004 Base wl_display_get_fd
000000000020dce0 g DO .data.rel.ro 0000000000000028 Base wl_display_interface
00000000000067a0 g DF .text 000000000000000c Base wl_display_prepare_read

最佳答案

wl_display_get_registry 函数和其他几个函数在头文件 wayland-client-protocols.h 中标记为 static inlineFunctions marked static inline will not have their symbols exported .这解释了 C 如何能够看到和使用该函数,而 Rust 却不能。

我们必须将 C 宏和静态内联函数重新实现为 Rust 函数:

pub enum WLDisplay {}
pub enum WLProxy {}
pub enum WLRegistry {}

const WL_DISPLAY_GET_REGISTRY: ::std::os::raw::c_uint = 1;

#[link(name = "wayland-client")]
extern "C" {
#[no_mangle]
static wl_registry_interface: WLInterface;

pub fn wl_display_connect(name: *const ::std::os::raw::c_char) -> *mut WLDisplay;
pub fn wl_display_disconnect(display: *mut WLDisplay) -> ();

pub fn wl_proxy_marshal_constructor(
proxy: *mut WLProxy,
opcode: ::std::os::raw::c_uint,
interface: *const WLInterface,
) -> *mut WLProxy;
}

#[repr(C)]
pub struct WLMessage {
pub name: *const ::std::os::raw::c_char,
pub signature: *const ::std::os::raw::c_char,
pub types: *const *const WLInterface,
}

#[repr(C)]
pub struct WLInterface {
pub name: *const ::std::os::raw::c_char,
pub version: ::std::os::raw::c_int,
pub request_count: ::std::os::raw::c_int,
pub requests: *const WLMessage,
pub event_count: ::std::os::raw::c_int,
pub events: *const WLMessage,
}

fn wl_display_get_registry(display: *mut WLDisplay) -> *mut WLRegistry {
let proxy: *mut WLProxy;

unsafe {
proxy = wl_proxy_marshal_constructor(
display as *mut _ as *mut WLProxy,
WL_DISPLAY_GET_REGISTRY,
&wl_registry_interface,
);
proxy as *mut _ as *mut WLRegistry
}
}

fn main() {
let display: *mut WLDisplay;
let registry: *mut WLRegistry;

unsafe {
display = wl_display_connect(::std::ptr::null());
if display.is_null() == true {
eprintln!("Unable to connect to the Wayland display server.");
return;
}
println!("Connected to Wayland display server.");

println!("Retrieving the registry from the Wayland display.");
registry = wl_display_get_registry(display);
if registry.is_null() == true {
eprintln!("Unable to retrieve registry.");
} else {
println!("Registry retrieved.");
}

wl_display_disconnect(display);
println!("Disconnected from Wayland display server.");
}
}

关于rust - 为什么 Rust 找不到 wl_display_get_registry?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50708059/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com