以下文章来源于江湖评谈 ,作者江湖评谈
前言
本篇先看下.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同目录,最后运行下:
# cp -r bin/Release/net8.0/linux-x64/publish/Rust.so src/
# export LD_LIBRARY_PATH= src/YYY.so //设置下库目录
# cargo run //运行结果正确
Result:8
结尾
以上就是Rust和.NET的互相操作,先是.NET调用Rust,再Rust调用.NET。可以看到Rust调用.NET是.NET AOT之后才能够调用的,托管环境下是不行的。
标签:调用,int,编程,so,NET9,dotnet,net,Rust From: https://www.cnblogs.com/o-O-oO/p/18592631