Как вызвать из C# генерируемую на Rust библиотеку

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#, в которых важна производительность, и пользоваться преимуществами обоих языков.

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи Greg James: How to call a Rust generated library from C#

Предыдущая статьяФормирование эффективной и целостной культуры ревью кода
Следующая статьяСамый уродливый шаблон React