C#调用Rust动态链接库DLL的案例

C#调用Rust动态链接库DLL的案例

项目概述

这是一个演示C#调用Rust动态链接库DLL的项目,包含:

  • C#主程序 (Program.cs)
  • Rust动态链接库 (rust_to_csharp目录)

使用C#创建一个net9的控制台项目,不使用顶级语句

dotnet new console --framework net9.0 --use-program-main

使用rust创建一个helloworld的lib项目生成一个C#能够调用的DLL

  1. 首先创建一个Rust库项目:
cargo new --lib rust_to_csharp
cd rust_to_csharp
  1. 修改Cargo.toml文件,添加以下内容:
[package]
name = "rust_to_csharp"
version = "0.1.0"
edition = "2021"

[lib]
name = "rust_to_csharp"
crate-type = ["cdylib"]  # 这将生成动态链接库
  1. 修改src/lib.rs文件,添加以下内容:
use std::ffi::CStr;
use std::os::raw::c_char;

#[no_mangle]
pub extern "C" fn hello_world() -> *const c_char {
    let s = "Hello from Rust!\0";  // 注意添加null终止符
    s.as_ptr() as *const c_char
}
  1. 编译Rust库:
cargo build --release
  1. 生成的DLL文件位于target/release目录下,例如rust_to_csharp.dll。

使用C#调用Rust动态链接库

  1. 在C#项目中添加对Rust动态链接库的引用:
using System;
using System.Runtime.InteropServices;

class Program {
    // 将其复制到C#项目的输出目录
    [DllImport("rust_to_csharp.dll")]
    private static extern IntPtr hello_world();
    
    static void Main() {
        IntPtr ptr = hello_world();
        string message = Marshal.PtrToStringAnsi(ptr);
        Console.WriteLine(message);  // 输出: Hello from Rust!
    }
}

注意事项

  1. 确保C#项目能访问到生成的DLL文件(可将其复制到C#项目的输出目录)
  2. 32位/64位需要匹配,建议都使用x64平台
  3. Rust字符串需要以null终止(\0)才能被C#正确读取
要在 C#调用 Rust 函数并返回结构体对象,可以使用 Rust 的 FFI(Foreign Function Interface)功能和 C# 的 Marshaling 功能来实现。 以下是一个基本的示例,假设 Rust 函数返回一个包含两个整数字段的结构体对象: 1. 在 Rust 中定义一个包含两个整数字段的结构体,并实现一个返回结构体对象的函数。 ```rust #[repr(C)] pub struct MyStruct { pub field1: i32, pub field2: i32, } #[no_mangle] pub extern "C" fn rust_function() -> MyStruct { MyStruct { field1: 1, field2: 2 } } ``` 2. 将 Rust 代码编译为动态链接库,使用命令行参数 --crate-type=cdylib。 ```bash $ rustc --crate-type=cdylib rust_lib.rs ``` 3. 在 C# 中使用外部函数声明 (DllImport) 和 C语言调用约定 (Calling Convention) 来声明 Rust 函数,并指定返回值类型为 IntPtr。 ```csharp using System; using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential)] public struct MyStruct { public int field1; public int field2; } class Program { [DllImport("rust_lib.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr rust_function(); static void Main(string[] args) { // 调用 Rust 函数并获取返回值指针 IntPtr ptr = rust_function(); // 将返回值指针转换为结构体对象 MyStruct result = Marshal.PtrToStructure<MyStruct>(ptr); // 打印结构体字段值 Console.WriteLine("Field1: " + result.field1); Console.WriteLine("Field2: " + result.field2); } } ``` 在上面的示例中,我们将 Rust 中的结构体类型显式地指定为 C 语言的结构体布局(#[repr(C)]),并将 C# 中的结构体类型与之相对应([StructLayout(LayoutKind.Sequential)])。然后,在 C# 中使用 Marshal.PtrToStructure 将返回值指针转换为结构体对象,从而实现了 Rust 函数返回结构体对象在 C# 中的使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值