点击上方蓝字 江湖评谈设为关注/星标
前言
本篇先看下.NET9调用Rust,然后看下Rust调用.NET9。它们相互的一个操作。
.NET9调用Rust
新建一个Rust动态库名为net的项目,进入到项目根目录
# cargo new net --lib
# cd net
Cargo.toml文件添加如下代码:
[lib]
name = "net" //导出库的名称
crate-type = ["cdylib"] //c风格的导出函数
src/lib.rs文件修改如下:
#[no_mangle] //防止Rust编译器改变函数名称
pub extern "C" fn add(a: i32, b: i32) -> i32 {
a + b
}
生成release的二进制可执行文件
# cargo build --release
linux扩展名为.so,库文件名称是lib+Cargo.toml的lib项指定的名称net。那么组合起来就是libnet.so,它即是我们需要被.NET调用的库。生成的库的目录如下:
# ls target/release/
build deps examples incremental libnet.d libnet.so
新建一个dotnet控制台项目,Program.cs改成如下代码,保存
# dotnet new console -n ABC
# cd ABC
# vim Program.cs
using System;
using System.Runtime.InteropServices;
class Program
{
// 声明外部函数
[DllImport("libnet.so", CallingConvention = CallingConvention.Cdecl)]
public static extern int add(int a, int b);
static void Main()
{
int result = add(2, 3);
Console.WriteLine($"The result is: {result}");
}
}
把上面Rust生成的libnet.so复制到dotnet项目的bin/Debug/net9.0目录下面去。此时我们运行dotnet项目,正确的打印出了5。
# dotnet run
The result is: 5
Rust调用.NET
新建一个dotnet类库项目,进入到项目根目录
# dotnet new classlib -n Rust
# cd Rust
csproj文件里面添加PublishAot
<PublishAot>true</PublishAot>
修改Class1.cs文件如下,然后编译下
# vim Class1.cs
using System.Runtime.InteropServices;
internal class Program
{
[UnmanagedCallersOnly(EntryPoint = "Add")]
public static int Add(int a, int b)
{
return a + b;
}
}
# dotnet publish -c Release -r linux-x64 --self-contained
生成的结果在bin/Release/net9.0/linux-x64/publish/下Rust.so文件。
我们新建一个rust程序,修改Cargo.toml以及srm/main.rs文件
# cargo new net //新建rust程序
# cd net
# vim Cargo.toml
[package]
name = "net"
version = "0.1.0"
edition = "2021"
[dependencies]
libloading = "0.7"
libc = "0.2"
# vim src/main.rs
use libc::c_int;
use libloading::{Library, Symbol};
fn main() {
unsafe {
let lib = Library::new("Rust.so").expect("加载库失败");
let func: Symbol<unsafe extern fn(c_int, c_int) -> c_int> = lib.get(b"Add").expect("无法找到函数");
let result = func(5, 3);
println!("Result: {}", result);
}
}
把Rust.so文件复制到Rust项目的根目录下的src文件里面,也即是跟main.rs同目录,最后运行下:
Result:8
结尾
以上就是Rust和.NET的互相操作,先是.NET调用Rust,再Rust调用.NET。可以看到Rust调用.NET是.NET AOT之后才能够调用的,托管环境下是不行的。
以上就是本篇内容,欢迎点赞,关注。
往期精彩回顾
Rust会取代C++吗?
Rust奇妙的玩出天际的花活儿
.NET9/Rust编译对比
关注公众号↑↑↑:江湖评谈