Appeler les fonctions Rust depuis Go

À un moment donné, il y avait un article sur Habr sur la façon d'appeler le code Rust de Go . L'article n'est pas mauvais, mais plutôt difficile à comprendre et repousse en fait les débutants du désir de se tourner vers les deux langues. Le but de cet article n'est pas tant de se lancer dans les tripes des appels multilingues, mais de montrer à quel point cela peut être facile.

image

Nous n'irons pas loin et prendrons l'exemple d'un livre sur l'apprentissage de la langue rouille.

Tout ce que cet exemple fait est de démarrer 10 threads, dans lesquels il incrémente la variable «x» à 5 millions et affiche un message sur la fin du flux.

use std::thread;

#[no_mangle]
pub extern "C" fn process() {
    let handles:Vec<_> = (0..10).map(|_|{
        thread::spawn(||{
            let mut x = 0;
            for _ in 0..5_000_000 {
                x += 1
            }
            x
        })
    }).collect();

    for h in handles {
        println!("Thread finished with count={}",
                 h.join().map_err(|_| "Could not join thread!").unwrap());
    }
    println!("Done!");
}


Vous devez également modifier le fichier cargo en y ajoutant une ligne
crate-type = ["cdylib"]
En conséquence, une bibliothèque sera créée avec la possibilité d'appeler des fonctions via l' interface de fonction étrangère (FFI) .

Il convient de noter que libembed.dylib est une bibliothèque sur Mac OS, sur Linux, ce sera libembed.so, et sur Windows, ce sera libembed.dll

Merci: bingo347


Cargo.toml
[package]
name = "embed"
version = "0.1.0"

[lib]
crate-type = ["cdylib"]


En général, c'est tout ce que vous avez à faire dans la bibliothèque Rust. Un exemple tiré du livre décrit cela plus en détail et nous ne nous attarderons pas là-dessus.

Nous compilons la bibliothèque avec la commande:
construction de cargaison - libération
Maintenant, notre objectif est d'appeler ce code à partir de l'application Go. Nous créons une application simple et à l'intérieur de notre projet, ajoutons le dossier lib dans lequel nous copions le fichier /target/release/libembed.dylib . A l'intérieur, nous créons un fichier avec le nom de la fonction et décrivons sa signature d'appel.

lib / process.h
void process();


Dans le fichier Go, nous ajoutons de telles directives et notre main.go ressemblera à ceci

package main

/*
#cgo LDFLAGS: -L./lib -lembed
#include "./lib/process.h"
*/
import "C"

func main() {
	C.process()
}


Assembler le projet
allez construire -ldflags = "- r / lib" main.go
Faites attention au paramètre ldflags, dans ce cas, tout ce que nous faisons est de définir le chemin vers l'éditeur de liens dynamique ELF.

Tout. Exécutez le programme et obtenez la sortie.



Il convient également de mentionner séparément que vous pouvez transférer les enseignements du programme Go à la bibliothèque Rust. Pour ce faire, nous transformons la fonction dans la bibliothèque Rust afin qu'elle prenne une valeur de chaîne.

extern crate libc;
use std::thread;
use std::ffi::CStr;

#[no_mangle]
pub extern "C" fn process(name: *const libc::c_char) {

    let buf_name = unsafe { CStr::from_ptr(name).to_bytes() };
    let str_name = String::from_utf8(buf_name.to_vec()).unwrap();

    let handles:Vec<_> = (0..10).map(|_|{
        thread::spawn(||{
            let mut x = 0;
            for _ in 0..5_000_000 {
                x += 1
            }
            x
        })
    }).collect();

    for h in handles {
        println!("{}:Thread finished with count={}\n",
                 str_name,
                 h.join().map_err(|_| "Could not join thread!\n").unwrap());
    }
    println!("Done!");
}


Nous assemblons notre projet, copions à nouveau la bibliothèque dans le dossier lib, modifions ainsi le fichier process.h
processus nul (char * nom);

Nous passons la ligne de l'application Go (dans notre cas: «Bonjour de Golang») .

package main

/*
#cgo LDFLAGS: -L./lib -lembed
#include "./lib/process.h"
*/
import "C"

func main() {
	C.process(C.CString("Hello from Golang !!"))
}


Tout. Exécutez le programme et obtenez la sortie.


All Articles