.NET9和Rust的互相调用

文摘   2024-12-05 14:03   新加坡  

点击上方蓝字 江湖评谈设为关注/星标




前言

本篇先看下.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.csusing 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 runThe result is: 5

Rust调用.NET

新建一个dotnet类库项目,进入到项目根目录

# dotnet new classlib -n Rust# cd Rust

csproj文件里面添加PublishAot

<PublishAot>true</PublishAot>

修改Class1.cs文件如下,然后编译下

# vim Class1.csusing 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.rsuse 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之后才能够调用的,托管环境下是不行的。

以上就是本篇内容,欢迎点赞,关注。

往期精彩回顾

Rust会取代C++吗?

Rust奇妙的玩出天际的花活儿

.NET9/Rust编译对比

关注公众号↑↑↑:江湖评谈 

江湖评谈
记录,分享,自由。
 最新文章