Rust e Python – 2

n3Continuo da qui l’esame della serie di post di TheK3nger sull’uso di Rust all’interno di codice Python e viceversa; oggi in particolare copio da How to use Rust in Python (Part 3).
Inoltre –per comodità– il Git è qui: THeK3nger/rust-python-integration-examples.

[W]e have seen how to pass not trivial data to Rust functions such as a Python list. It is still not enough, though. In many cases we need to pass complex data structure back and forth from a Rust library. We may need to pass quaternions [davvero qualcuno usa quella roba lì?], 3D points, trees, a list of “books”… In short: anything.

Lato Rust

As usual, the first thing to do is to implement the Rust library function. This time we need to design first a struct that will represent our complex object. We chose to represent 2D points.

#[repr(C)]
pub struct Point {
    x: f64,
    y: f64,
}

This is a classic rust struct declaration, but we need to use #[repr(C)] to explain to the compiler that Point is a C struct.

Now, we can simply implement the desired function. In this example we will implement a function that, given two Point  representing a segment, returns the midpoint of the segment.

#[no_mangle]
pub extern fn middle(p1: Point, p2: Point) -> Point {
    Point { x: (p1.x + p2.x)/2.0, y: (p1.y + p2.y)/2.0 }
}

Lato Python

Python side is slightly more complicated. Also in Python, we need first to declare the Point.

class Point(ctypes.Structure):
    _fields_ = [("x", ctypes.c_double), ("y", ctypes.c_double)]
    
    def __str__(self):
        return "Point ({},{})".format(self.x, self.y)

The class representing our C/Rust struct is different from the usual one:

  • The class must extend the ctypes.Structure class defined in ctypes.
  • The fields of the C struct must be defined using the builtin _fields_ attribute. This attribute must contain a list of tuples. Each tuple must contain the 1) name of the field and 2) the type of the field according the ctypes declaration. In our case Point has two fields, “x” and “y”, both doubles.

Now it is time to setup our Rust function. We specify the type declaration for our function.

lib.middle.argtypes = (Point, Point)
lib.middle.restype = Point

Then we can use this function as usual!

p1 = Point(1.0, 5.0)
p2 = Point(1.0, 10.0)

res_point = lib.middle(p1, p2)
print(res_point)

And we have done. It is not so difficult, isn’t it? Certo, semplicissimo, adesso provo, ecco il file rp_points.py:

import ctypes

lib = ctypes.CDLL("./target/release/librustypython.so")

class Point(ctypes.Structure):
    _fields_ = [("x", ctypes.c_double), ("y", ctypes.c_double)]
    
    def __str__(self):
        return "Point ({},{})".format(self.x, self.y)

# Then we specify as usual the type declaration of the Rust function.
lib.middle.argtypes = (Point, Point)
lib.middle.restype = Point

# And then we can easily use it as a native python function!
p1 = Point(1.0, 5.0)
p2 = Point(1.0, 10.0)

res_point = lib.middle(p1, p2)
print(res_point)

k6

OK 😀 come già detto TheK3nger rockz! 😀 Rust & Python too 😀

Devo davvero imparare bene Rust, da usarsi per le operazioni impegnative.

:mrgreen:

Posta un commento o usa questo indirizzo per il trackback.

Trackback

  • Linux e Windows (e me) | Ok, panico su 24 marzo 2016 alle 17:01

    […] limitato. E (rigarda me) Rust è troppo difficile (ho anche copiato TheK3nger, qui e qui ma non ho convinto). E i linguaggi funzionali (Lisp e tutti gli altri) no, solo per me. Ma in […]

  • Rust – il linguaggio – 51 | Ok, panico su 20 aprile 2016 alle 08:21

    […] Uhmmm… oltre che molto specifico l’argomento è già stato trattato in modo comprensibile anche agli umani come me, copiando TheKeng3r, qui e qui. […]

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.

%d blogger hanno fatto clic su Mi Piace per questo: