Rust是否有类似dlopen的功能?

35

Rust是否有一种使程序可插拔的方式。在C语言中,我创建的插件是.so文件,使用dlopen加载。Rust是否提供了原生方法来完成相同的操作?

3个回答

31

Rust FAQ 正式推荐使用 libloading。除此之外,我知道还有三种不同的选项:

我没有尝试过其中任何一种方法,所以我不能说哪种最好或每种变体的优缺点是什么。至少我强烈建议不要使用std::dynamic_lib,因为它已经被弃用,并且将来很可能会被私有化。


是的,libloading 现在似乎是这样做的官方方式。 - Matt

13

没错,

以下是完整的用例示例:

use std::unstable::dynamic_lib::DynamicLibrary;
use std::os;

fn load_cuda_library()
{

    let path = Path::new("/usr/lib/libcuda.so");

    // Make sure the path contains a / or the linker will search for it.
    let path = os::make_absolute(&path);

    let lib = match DynamicLibrary::open(Some(&path)) {
        Ok(lib) => lib,
        Err(error) => fail!("Could not load the library: {}", error)
    };

    // load cuinit symbol

    let cuInit: extern fn(u32) -> u32 = unsafe {
        match lib.symbol("cuInit") {
            Err(error) => fail!("Could not load function cuInit: {}", error),
            Ok(cuInit) => cuInit
        }
    };

    let argument = 0;
    let expected_result = 0;
    let result = cuInit(argument);

    if result != expected_result {
        fail!("cuInit({:?}) != {:?} but equaled {:?}",
                argument, expected_result, result)
    }
}

fn main()
{
    load_cuda_library();
}

我认为这会加载任何与C兼容的库?而且我认为像使用dlopen一样加载符号实际上并不知道函数签名,这意味着您无法确定是否使用正确的参数调用函数。这似乎破坏了Rust所提供的安全性,但我想随意加载其他代码本来就不是最安全的事情。 - Matt
1
你说得很对。任何与C兼容的库都可以被加载。不幸的是,这会破坏安全性。然而上述方案可能会发生变化。Rust开发人员将会添加一种安全的动态加载库的方式,请参见https://github.com/mozilla/rust/issues/458。 - Alexander Samoilov
3
记录一下,问题编号 #458 已经关闭,新的问题编号是 https://github.com/rust-lang/rust/issues/15040。 - Flavius
已经再次搬迁(因为它没有进入 Rust 1.0 版本):https://github.com/rust-lang/rfcs/issues/661 - Per Lundberg
我认为这不应该是批准的答案@Matt,它建议在Rust中使用不稳定、不易访问的功能。 Rust FAQ给出了与此不同的建议(有关详细信息,请参见我对此问题的回答)。 - Per Lundberg

3
是的。有一个模块 std::unstable::dynamic_lib,可以实现动态加载库。然而,它是高度实验性 API(std::unstable 中的所有内容都没有文档)。如 @dbaupp 建议的那样,最好的文档是源代码(当前版本为 af9368452 )。

1
(源代码是最好的文档。) - huon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接