使用Rust创建库,并在exe中调用

文章目录

使用Rust创建库,并在exe中调用

使用cargo new创建项目时,有项目类型的选项:

  • –bin:编译为可执行文件
  • –lib:编译为库文件

默认的,是–lib。事实上,Rust能创建的库的种类有下面几种:

  • rlib:Rust库,这是cargo new默认的种类,只能被Rust调用;
  • dylib:Rust规范的动态链接库,windows上编译成.dll,linux上编译成.so,也只能被Rust调用;
  • cdylib:满足C语言规范的动态链接库,windows上编译成.dll,linux上编译成.so,可以被其他语言调用
  • staticlib:静态库,windows上编译成.lib,linux上编译成.a,可以被其他语言调用

只是被Rust调用的话,默认的rlib是最好的选择,如果想用其他的种类,无法直接使用cargo指定,只能手动修改Cargo.toml。

[lib]
crate-type = ["rlib", "dylib", "cdylib", "staticlib"]

cargo允许同时设置多种类型,同一套代码,同时编译为多种类型。

创建numrust库

可以使用cargo创建项目:

cargo new numrust

也可以使用Clion为我们创建,两者创建的文件是相同的:

使用Rust创建库,并在exe中调用

在库中创建mod

Rust使用mod关键字创建命名空间,自动生成的代码中,已经包含了一个mod tests:

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}

mod默认为私有,也就是说,这个tests并不会被库导出,它是为我们测试而准备的。我们可以创建自己的mod:

pub mod numrust {       // 创建公有的mod
    pub fn hello() {    // 创建公有的函数
        println!("hello numrust")
    }
}

要想在tests中调用,需要了解mod的路径规则。Rust使用“::”来分隔命名空间,使用crate、self、super三个关键字来表示路径的起点:

  • crate:类似于根目录
  • self:指当前mod,类似于“.”
  • super:指当前mod的父mod,类似于“…”

numrust与tests是同级的,所以在tests中调用numrust有两种方式:

crate::numrust::hello();
super::numrust::hello();

除此之外,还可以使用use引用mod。在Python中,人们都习惯这样引入numpy:

import numpy as np

这在Rust中同样可以:

#[cfg(test)]
mod tests {
    use super::numrust as nr;

    #[test]
    fn it_works() {
        nr::hello();
        assert_eq!(2 + 2, 4);
    }
}

要调试我们的库,可以直接使用命令:

> cargo test
    Finished test [unoptimized + debuginfo] target(s) in 0.01s
     Running unittests (target\debug\deps\numrust-0bda5bdf4b187237.exe)

running 1 test
test tests::it_works ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

也可以在Clion中运行:

使用Rust创建库,并在exe中调用

在exe中调用库

下面再创建一个可执行的项目,来调用刚刚的库。

cargo new --bin numrustexe

可使用Clion创建:

使用Rust创建库,并在exe中调用

然后修改Cargo.toml,指定库项目Cargo.toml所在的目录:

[dependencies]
numrust = { path = "../numrust" }

然后修改main.rs:

extern crate numrust;           // 导入外部crate
use numrust::numrust as nr;     // 引用numrust,第一个为库名,第二个为库中mod的名称

fn main() {
    nr::hello();
}

到此,就可以运行了:

> cargo run
   Compiling numrustexe v0.1.0 (C:\Users\zhangmh\Desktop\MarkDown\numrust\code\numrustexe)
    Finished dev [unoptimized + debuginfo] target(s) in 0.78s
     Running `target\debug\numrustexe.exe`
hello numrust

当numrust库被修改时,cargo会先编译numrust,然后再编译numrustexe,保证每次运行都是最新的结果。

上一篇:函数调用顺序,pow函数2021.3.2


下一篇:rust创建自己的库文件