如何在共享库中动态调用函数? [英] How to dynamically call a function in a shared library?

查看:57
本文介绍了如何在共享库中动态调用函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Rust项目,设置为可执行文件.我正在尝试动态调用同样用Rust编写的外部共享库.我已经在发布时编译了外部库,并且尝试了两种包装类型 cdylib dylib .

I have a Rust project, set as an executable. I am trying to call an external shared library, also written in Rust, dynamically. I have the external library compiled on release, and I have tried both crate types cdylib and dylib.

我正在使用板条箱 libloading ,该箱声称能够动态加载共享库函数,只要它们仅使用原始参数即可.当我尝试使用此板条箱运行代码时,我不断收到此错误.

I am using the crate libloading, which claims to be able to dynamically load shared library functions, as long as they only use primitive arguments. I keep getting this error when I try to run my code using this crate.

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: GetProcAddress { source: Os { code: 127, kind: Other, message: "The specified procedure could not be found." } }', src\main.rs:14:68
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


main.rs/main():

    let now = Instant::now();

    unsafe {
        let lib = libloading::Library::new(
            "externtest.dll").unwrap();
        let foo3: Symbol<extern fn(i32) -> i32> = lib.get(b"foo").unwrap();

        println!("{}", foo(1));
    }

    let elapsed = now.elapsed();
    println!("Elapsed: {:?}", elapsed);

lib.rs:

pub extern "C" fn foo3(i:i32) -> i32{
    i
}

推荐答案

首先,您的库函数称为"foo3" ,但是您尝试加载符号"foo" .

First, your library function is called "foo3", but you're trying to load the symbol "foo".

第二,由于重整,库函数的符号可能与名称不匹配.您需要告诉编译器不要使用#[no_mangle] 属性:

Second, the library function's symbol may not match it's name due to mangling. You need to tell the compiler not to do that with the #[no_mangle] attribute:

#[no_mangle]
pub extern "C" fn foo(i: i32) -> i32 {
    i
}

第三,这主要是一种风格选择,但是在定义符号时,我会指定ABI extern"C" .即使 extern ,也没有明确的ABI使用"C" ABI ,我发现最好是明确的.

Third, this is mostly a stylistic choice, but I'd specify the ABI extern "C" when defining your symbol. Even though extern with no epecified ABI uses the "C" ABI, I've found it better to be explicit.

use libloading::{Library, Symbol};

fn main() {
    unsafe {
        let lib = Library::new("externtest.dll").unwrap();
        let foo = lib
            .get::<Symbol<extern "C" fn(i32) -> i32>>(b"foo")
            .unwrap();

        println!("{}", foo(1));
    }
}

以上内容应该可以正常工作.

The above should work without issue.

这篇关于如何在共享库中动态调用函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆