Rust — невероятно быстрый язык системного программирования с предотвращением аварийного завершения программ и гарантированной потокобезопасностью.
C# — современный объектно-ориентированный язык для разработки приложений Windows.
У обоих языков имеются сильные и слабые стороны: в определенных сценариях для реализации частей системы, в которых важна производительность, стоит использовать Rust, а для остальной части приложения — C#. В таких случаях нужно вызывать код Rust из C#.
Вот как из C# вызвать библиотеку на Rust.
Шаг 1. Создаем библиотеку на Rust
Она будет использоваться в приложении на C# и создается с помощью ключевого слова lib
в файле Cargo.toml
:
[lib]
name = "rust_library"
crate-type = ["cdylib"]
Далее пишем вызываемый из C# код Rust, например функцию, в которой принимаются два целых числа, а возвращается их сумма:
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
a + b
}
Атрибут #[no_mangle]
на Rust отключает искажение имен: имя функции становится доступным из C#. В блоке extern "C"
указывается соглашение о вызовах C, необходимое для взаимодействия с C#.
Шаг 2. Выполняем сборку библиотеки на Rust
Написав код Rust, делаем сборку библиотеки:
cargo build --release
Этой командой в каталоге target/release
генерируется файл динамически подключаемой библиотеки — .dll
на Windows, .so
в Linux и .dylib
на macOS, — используемый в приложении на C#.
Шаг 3. Вызываем из C# библиотеку на Rust
Вызовем из C# функции библиотеки на Rust. Для этого используем P/Invoke, то есть службы обращения к платформе. Этот механизм .NET применяется для вызова функций в DLL, библиотеках динамической компоновки с неуправляемым кодом.
Вот как из C# вызвать функцию add
на Rust:
using System;
using System.Runtime.InteropServices;
class Program {
[DllImport("rust_library.dll")]
public static extern int add(int a, int b);
static void Main(string[] args) {
Console.WriteLine(add(3, 4));
}
}
Атрибутом DllImport
компилятору C# указывается на использование P/Invoke для вызова функции add
в библиотеке на Rust, а ключевым словом extern
— на то, что функция реализована извне.
Заключение
В статье вы узнали, как из C# вызвать библиотеку на Rust: создать ее, выполнить сборку и с помощью P/Invoke вызвать из C# ее функции.
Теперь вы можете применять Rust для реализации частей приложений на C#, в которых важна производительность, и пользоваться преимуществами обоих языков.
Читайте также:
- Эволюция кортежей в C#
- Тип Result в Rust
- 8 рекомендаций по написанию читаемого кода на C# с помощью .NET 6
Читайте нас в Telegram, VK и Дзен
Перевод статьи Greg James: How to call a Rust generated library from C#