Einführung in "Einführung in die praktische Rostprogrammierung" (Tag 4) Aufrufen von Rust von Ruby

Überblick

"Einführung in die praktische Rostprogrammierung" Siehe S. 421-427 und rufen Sie Rust-Funktionen von Ruby aus auf. Übrigens ist heute (Freitag, 4. September 2020) Ruby Kaigi.

Bereit für Windows

Laden Sie Ruby für Windows von [RubyInstaller für Windows] herunter (https://rubyinstaller.org/downloads/). Zum Zeitpunkt des Schreibens dieses Artikels ist das neueste Ruby + Devkit 2.7.1-1 (x64). 1-1-x64.exe).

01_RubyInstaller2_01.png

Es gibt "Wenn Sie sich nicht sicher sind, drücken Sie ENTER", drücken Sie ENTER, um fortzufahren.

02_RubyInstaller2_02.png

War ENTER dasselbe wie das Drücken von 3, da dort steht, dass "MSYS2 und MINGW Developent Toolchain erfolgreich installiert wurden"? Drücken Sie nun ENTER, um die Installation abzuschließen.

Überprüfen Sie den Betrieb von Ruby unter Windows PowerShell.

PS > ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x64-mingw32]

Sie können dies mit VS-Code überprüfen, indem Sie TERMINAL erneut öffnen.

S.421 Beispiel: Rufen Sie eine Rust-Funktion von Ruby auf.

Erstellen Sie ein Projektverzeichnis für die Durchführung der Experimente auf S.421.

PS > cargo new ffitest
     Created binary (application) `ffitest` package

Erstellen Sie unter ffitest ein Beispielverzeichnis, schreiben Sie Ruby-Code und experimentieren Sie mit der Ruby-Verarbeitung.

ffitest/sample/add_array.rb


def add_array(n,x)
    a = Array.new(n,0)
    x.times do
        for i in 0..x-1
            a[i] += 1
        end
    end
    a.sum
end

puts add_array(ARGV[0].to_i, ARGV[1].to_i)

Measure-Command entspricht "time" unter Linux Befehl.

PS ffitest\sample> Measure-Command {ruby add_array.rb 10000 10000}       


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 8
Milliseconds      : 53
Ticks             : 80530169
TotalDays         : 9.32062141203704E-05
TotalHours        : 0.00223694913888889
TotalMinutes      : 0.134216948333333
TotalSeconds      : 8.0530169
TotalMilliseconds : 8053.0169

In TotalSeconds können Sie sehen, dass es ungefähr 8 Sekunden dauert.

Als nächstes kommt die Rostseite. Benennen Sie src / main.rs in src / add_array.rs um.

src/add_array.rs


fn add_array(n: u64, x: u64) -> u64 {
    let mut a = vec![0u64; n as usize];
    for _ in 0..x {
        for i in 0..n as usize {
            a[i] += 1;
        }
    }
    a.iter().sum()
}

use std::env;
fn main() {
    let args: Vec<_> = env::args().collect();
    let n = args[1].parse::<u64>().unwrap();
    let x = args[2].parse::<u64>().unwrap();
    println!("{}", add_array(n, x));
}

Fügen Sie die Ausführungseinstellung von add_array zu Cargo.toml hinzu.

Cargo.toml


[[bin]]
name = "add_array"
path = "src/add_array.rs"

S.422 Führen Sie unten eine Build & Execution-Bestätigung durch.

PS ffitest> cargo build --release
   Compiling ffitest v0.1.0 (ffitest)
    Finished release [optimized] target(s) in 1.29s     
PS ffitest> Measure-Command {./target/release/add_array 10000 10000}     


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 93
Ticks             : 935455
TotalDays         : 1.0827025462963E-06
TotalHours        : 2.59848611111111E-05
TotalMinutes      : 0.00155909166666667
TotalSeconds      : 0.0935455
TotalMilliseconds : 93.5455

0,09 Sekunden. Es ist sehr schnell.

S.423 Bibliothek

Erstellen Sie ein Projektverzeichnis für die Bibliothek.

PS > cargo new --lib addarray
     Created library `addarray` package

[Dynamische Bibliotheksspezifikation] in Cargo.toml (https://doc.rust-lang.org/edition-guide/rust-2018/platform-and-target-support/cdylib-crates-for-c-interoperability.html) )Ich mache.

addarray/Cargo.toml


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

Durch die bisherige Arbeit wurde src / lib.rs erstellt. Der Inhalt ist wie folgt.

src/lib.rs


#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}

Löschen Sie den obigen Code und schreiben Sie ihn gemäß der zweiten lib.rs auf S.424.

src/lib.rs


#[no_mangle]
pub extern "C" fn add_array(n: u64, x: u64) -> u64 {
    let mut a = vec![0u64; n as usize];
    for _ in 0..x {
        for i in 0..n as usize {
            a[i] += 1;
        }
    }
    a.iter().sum()
}

Bauen. Aufgrund verschiedener Gedanken und Fehler scheint es, wenn --target = x86_64-pc-windows-msvc gesetzt ist, eine DLL zu sein, die mit diesem Ruby ausgeführt werden kann (unzureichende Forschung).

PS > cargo build --release --target=x86_64-pc-windows-msvc       
   Compiling addarray v0.1.0 (addarray)
    Finished release [optimized] target(s) in 0.87s   

Überprüfen Sie die erstellte Bibliothek.

PS addarray> ls .\target\x86_64-pc-windows-msvc\release\


Verzeichnis: addarray\target\x86_64-pc-windows-msvc\release


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2020/09/04     --:--                .fingerprint
d-----       2020/09/04     --:--                build
d-----       2020/09/04     --:--                deps
d-----       2020/09/04     --:--                examples
d-----       2020/09/04     --:--                incremental
-a----       2020/09/04     --:--              0 .cargo-lock
-a----       2020/09/04     --:--            109 addarray.d
-a----       2020/09/04     --:--         128512 addarray.dll
-a----       2020/09/04     --:--            980 addarray.dll.exp
-a----       2020/09/04     --:--           1942 addarray.dll.lib
-a----       2020/09/04     --:--         937984 addarray.pdb

OK, wenn addarray.dll erstellt wird.

S.425 Anruf von Ruby

Installieren Sie Ruby ffi.

PS > gem install ffi
Fetching ffi-1.13.1-x64-mingw32.gem
Successfully installed ffi-1.13.1-x64-mingw32
Parsing documentation for ffi-1.13.1-x64-mingw32
Installing ri documentation for ffi-1.13.1-x64-mingw32
Done installing documentation for ffi after 1 seconds
1 gem installed

Der Ruby-Quellcode wird als addarray / sample / add_array_rs.rb erstellt. Seien Sie vorsichtig, wenn Sie den DLL-Pfad angeben. Ich war süchtig danach, einen relativen Pfad anzugeben, also habe ich einen absoluten Pfad angegeben.

addarray/sample/add_array_rs.rb


require 'ffi'

module AddArray
    extend FFI::Library
    ffi_lib 'C:\your\path\addarray\target\x86_64-pc-windows-msvc\release\addarray.dll'
    attach_function :add_array, [:uint64, :uint64], :uint64
end

puts AddArray::add_array(ARGV[0].to_i, ARGV[1].to_i)

S.426 Ausführungsbestätigung

PS addarray\sample> Measure-Command {ruby .\add_array_rs.rb 10000 10000} 


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 311
Ticks             : 3111198
TotalDays         : 3.60092361111111E-06
TotalHours        : 8.64221666666667E-05
TotalMinutes      : 0.00518533
TotalSeconds      : 0.3111198
TotalMilliseconds : 311.1198

0,3 Sekunden. Es ist langsamer als 0,09 Sekunden, aber ursprünglich waren es 8 Sekunden, also ist es eine große Verbesserung.

Extra: Umgebungseinstellungen für die Ruby & Rust-Integration für Windows

Unter Windows muss Rust eine geeignete DLL entsprechend der Ruby-Umgebung erstellen. Ich war süchtig nach der Falle und untersuchte verschiedene Notizen.

Beim Hinzufügen eines Ziels von MINGW64.

PS > rustup target add x86_64-pc-windows-gnu
info: downloading component 'rust-std' for 'x86_64-pc-windows-gnu'
info: installing component 'rust-std' for 'x86_64-pc-windows-gnu'
info: Defaulting to 500.0 MiB unpack ram
 14.1 MiB /  14.1 MiB (100 %)  10.9 MiB/s in  1s ETA:  0s

Verwenden Sie rustup, um die Liste der Ziele anzuzeigen.

PS addarray> rustup show
Default host: x86_64-pc-windows-msvc
rustup home:  .rustup

installed targets for active toolchain
--------------------------------------

i686-pc-windows-gnu
x86_64-pc-windows-gnu
x86_64-pc-windows-msvc

active toolchain
----------------

stable-x86_64-pc-windows-msvc (default)
rustc 1.45.2 (d3fb005a3 2020-07-31)

Als ich "Cargo Build" machte, war ich wütend, dass ich x86_64-w64-mingw32-gcc nicht finden konnte. PFAD hinzufügen.

PS > $ENV:Path="C:\Ruby27-x64\msys64\mingw64\bin;"+$ENV:Path

Bauen.

PS addarray> cargo build --release --target=x86_64-pc-windows-gnu --verbose
       Fresh addarray v0.1.0 (addarray)
    Finished release [optimized] target(s) in 0.02s

addarray.dll wird erstellt.

PS addarray> ls .\target\x86_64-pc-windows-gnu\release


Verzeichnis: addarray\target\x86_64-pc-windows-gnu\release


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2020/09/04     --:--                .fingerprint
d-----       2020/09/04     --:--                build
d-----       2020/09/04     --:--                deps
d-----       2020/09/04     --:--                examples
d-----       2020/09/04     --:--                incremental
-a----       2020/09/04     --:--              0 .cargo-lock
-a----       2020/09/04     --:--            108 addarray.d
-a----       2020/09/04     --:--        3689956 addarray.dll
-a----       2020/09/04     --:--           2056 libaddarray.dll.a

add_array_rs.rb Änderungs- und Funktionsprüfung

Ändern Sie die DLL-Spezifikation im Ruby-Code erneut.

add_array_rs.rb


require 'ffi'

module AddArray
    extend FFI::Library
    ffi_lib 'C:\your\path\addarray\target\x86_64-pc-windows-gnu\release\addarray.dll'
    attach_function :add_array, [:uint64, :uint64], :uint64
end

puts AddArray::add_array(ARGV[0].to_i, ARGV[1].to_i)

Betrachtung

  1. Achten Sie beim Experimentieren mit Windows auf die Ausführungsumgebung. Es gibt verschiedene Fallstricke wie Mingw, 32-Bit, 64-Bit usw.

Recommended Posts

Einführung in "Einführung in die praktische Rostprogrammierung" (Tag 4) Aufrufen von Rust von Ruby
Einführung in "Einführung in die praktische Rostprogrammierung" (Tag 3)
Einführung in die praktische Programmierung
Beginnen wir mit der parallelen Programmierung
Wie fange ich mit schlank an?
Einführung in Ruby (aus anderen Sprachen)
Ich habe versucht, mit Web Assembly zu beginnen
[Hinweis] Erste Schritte mit Rspec
Die Programmierung von Ruby-Spielen begann mit einem Browser: Einführung in Nyle-Canvas (DXRuby-Stil)
Einführung in Ruby 2
Erste Schritte mit Eclipse Micro Profile
Versuchen Sie, den API-Schlüssel von Redmine mit Ruby zu erhalten
Rails-Anfänger haben versucht, mit RSpec zu beginnen
Einführung in die Programmierung für Studenten (von Zeit zu Zeit aktualisiert)
Ich habe versucht, mit Spring Data JPA zu beginnen
Wie man mit cli jdk etc. von oracle bekommt
Erste Schritte mit Ruby
Von Java zu Ruby !!
Beginnen Sie mit Gradle
Jetzt ist es an der Zeit, mit der Stream-API zu beginnen
Erste Schritte mit JDBC mit PostgresSQL unter MacOS
Ich habe versucht, mit Swagger mit Spring Boot zu beginnen
Beginnen Sie mit Spring Boot
Erste Schritte mit Ruby-Modulen
[ruby] Eine Methode mit einem Argument aufrufen
Einfache Codeüberprüfung für den Einstieg in Jenkins / SonarQube: Statische Analyse
Abrufen und Hinzufügen von Daten aus dem Firebase Firestore in Ruby