Dan*_*son 5 c linker dynamic-linking rust
该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
}
Run Code Online (Sandbox Code Playgroud)
它会更接近以下 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;
}
Run Code Online (Sandbox Code Playgroud)
编译与
clang -o test test.c -ldl # or your cc of choice
Run Code Online (Sandbox Code Playgroud)
或者它会转化为诸如 using 之类的东西clang <other stuff> -lwayland-core吗?还是我完全错了,朝着错误的方向前进?
以下是我通过阅读The Rust Reference找到的唯一文档
link- 指示应链接到本机库,以便正确链接此块中的声明。link支持可选的kind有三个可能的值键:dylib,static,和framework.
我不知道这是真的,我只是根据编译器的输出得出这个答案。
我使用的是 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
Run Code Online (Sandbox Code Playgroud)
其中的一些亮点:
"cc" [...] "-l" "wayland-client"
ld: library not found for -lwayland-client
从该输出来看,我相信这是对动态库进行正常的编译时链接,而不是动态库的运行时加载。
动态库的运行时加载过去由 处理std::dynamic_lib,但现在应该使用 crate。我不确定哪个板条箱最好,但我确实找到了libloading。
作为一些社论,我建议创建一个mylibrary-sys简单地公开直接 FFI 绑定的箱子。在该箱中,使用密钥links指定您要链接到本机库。这使得 Cargo 能够确保本机库仅链接一次。那么你不需要任何属性。
| 归档时间: |
|
| 查看次数: |
510 次 |
| 最近记录: |