gpt4 book ai didi

c - Rust 链接属性的内部工作原理与 C 中的链接相比如何?

转载 作者:太空狗 更新时间:2023-10-29 15:35:05 26 4
gpt4 key购买 nike

我对 link 的简单程度印象深刻属性链接到共享库。但是,我很好奇该属性的详细信息以及它与 C 中的链接相比如何。例如,给定以下 Rust 代码

#[allow(bad_style)]

struct wl_display;

fn main() {
#[link(name="wayland-client", kind="dylib")]
extern {
fn wl_display_connect(name: *const u8) -> *mut wl_display;
}

// do work
}

它会更接近于类似于以下 C 代码的代码吗?

#include <stdio.h>
#include <dlfcn.h>

struct wl_display;

int main() {
struct wl_display* (*pwl_display_connect)(const char *name);
char* error;

void* handle = dlopen("/usr/lib/libwayland-client.so", RTLD_LAZY);

if(!handle) {
fprintf(stderr, "Error opening lib: %s\n", dlerror());
exit(1);
}

pwl_display_connect = dlsym(handle, "wl_display_connect");

// do work

if(!pwl_display_connect) {
fprintf(stderr, "Error loading function: %s\n", dlerror());
exit(1);
}

if(dlclose(handle) < 0) {
fprintf(stderr, "Error closing lib: %s\n", dlerror());
exit(1);
}

return 0;
}

编译为

clang -o test test.c -ldl # or your cc of choice

或者它会转化为类似使用 clang <other stuff> -lwayland-core 的东西吗? ?还是我完全错了,走错了方向?

以下是我通过阅读 The Rust Reference 找到的唯一文档

link - indicate that a native library should be linked to for the declarations in this block to be linked correctly. link supports an optional kind key with three possible values: dylib, static, and framework.

编辑:

The Rust Programming LanguageAdvanced Linking 下有更多信息

最佳答案

不知道这是真的,我只是根据编译器的输出得出这个答案。

我在 OS X 上,没有安装任何与 Wayland 相关的东西。如果我获取您的代码并使用 cargo build --verbose 对其进行编译,我将得到以下输出(稍作清理):

   Compiling wat v0.1.0 (file:///private/tmp/wat)
Running `rustc src/main.rs --crate-name wat --crate-type bin -g --out-dir /private/tmp/wat/target/debug --emit=dep-info,link -L dependency=/private/tmp/wat/target/debug -L dependency=/private/tmp/wat/target/debug/deps`
error: linking with `cc` failed: exit code: 1
note: "cc" "-m64" "-L" "/Users/shep/Projects/rust/x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib" "/private/tmp/wat/target/debug/wat.0.o" "-o" "/private/tmp/wat/target/debug/wat" "-Wl,-dead_strip" "-nodefaultlibs" "-L" "/private/tmp/wat/target/debug" "-L" "/private/tmp/wat/target/debug/deps" "-L" "/Users/shep/Projects/rust/x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib" "-l" "wayland-client" "/Users/shep/Projects/rust/x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/libstd-ca1c970e.rlib" "/Users/shep/Projects/rust/x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/libcollections-ca1c970e.rlib" "/Users/shep/Projects/rust/x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/librustc_unicode-ca1c970e.rlib" "/Users/shep/Projects/rust/x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/librand-ca1c970e.rlib" "/Users/shep/Projects/rust/x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/liballoc-ca1c970e.rlib" "/Users/shep/Projects/rust/x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/liballoc_jemalloc-ca1c970e.rlib" "/Users/shep/Projects/rust/x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/liblibc-ca1c970e.rlib" "/Users/shep/Projects/rust/x86_64-apple-darwin/stage2/lib/rustlib/x86_64-apple-darwin/lib/libcore-ca1c970e.rlib" "-l" "System" "-l" "pthread" "-l" "c" "-l" "m" "-l" "compiler-rt"
note: ld: library not found for -lwayland-client

其中的一些亮点:

"cc" [...] "-l" "wayland-client"

ld: library not found for -lwayland-client

从该输出来看,我相信这是在执行正常的编译时链接到动态库,而不是动态库的运行时加载。


以前由 std::dynamic_lib 处理的动态库的运行时加载,但现在应该使用 crate 。我不确定哪个 crate 最好,但我确实找到了 libloading .


作为一些社论,我建议创建 a mylibrary-sys crate这只是公开了直接的 FFI 绑定(bind)。在那个 crate 中,使用 the links key指定您要链接到 native 库。这允许 Cargo 确保原生库只被链接一次。那么你不需要任何属性。

关于c - Rust 链接属性的内部工作原理与 C 中的链接相比如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34358084/

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