2015-06-15 8 views
5

Ich habe eine Rust-Bibliothek, die über das Ctypes-Modul in Python importiert werden muss. Mein Ziel ist es, Rust-Funktionen zu verwenden, die Vec<T>/i32 als Argumente annehmen und diese Typen von Python zurückgeben. Zur Zeit kann ich Ganzzahlen an die Rust-Funktionen übergeben und sie Listen/Ganzzahlen zurückgeben lassen. Hier ist der aktuelle Code:Python-Liste an Rust-Funktion übergeben

Python:

import ctypes 
from ctypes import cdll 

class List_4(ctypes.Structure): 
    _fields_ = [("array", ctypes.ARRAY(ctypes.c_int32, 4))] 

rust = cdll.LoadLibrary("target/debug/py_link.dll") 
rust.function_vec.restype = List_4 

foobar = rust.function_i32(5) 
barbaz = rust.function_vec([1, 2, 3, 4]) # Throws error: Don't know how to convert parameter 

print foobar 
print barbaz 

Rust:

#[repr(C)] 
pub struct List_4 { 
    array: [i32; 4] 
} 

#[no_mangle] 
pub extern fn function_i32(number: i32) -> i32 { 
    number 
} 

#[no_mangle] 
pub extern fn function_vec(list: List_4) -> List_4 { 
    List_4 { array: [1, 2, 3, 5] } 
} 

Was ich brauche Hilfe mit einer Python-Liste als Argument an eine Rust Funktion übergeben. Meine beste Vermutung ist es, eine ctypes.ARRAY an die Funktion statt eine Liste zu übergeben, aber ich bin mir nicht sicher, wie man eine Python-Liste in diesen Typ konvertieren soll.

Hinweis: Ich habe versucht, die Rust-Code von this related question aber es sagt "Verknüpfung mit` gcc` fehlgeschlagen: Exit-Code: 1 "und" schlechte Umzug Adresse ", wenn ich versuche, es zu kompilieren.

+0

Ist es möglich, diese Frage zu stoßen? Niemand wird es jetzt sehen, und ich möchte lieber, dass die Leute diese Frage beantworten, nicht eine neue. – pengowen123

+0

Ja, ich bin auf Windows. Danke, dass du mich informiert hast, ich könnte beides tun, aber es wäre einfacher, ein Array zu verwenden. Es wäre jedoch nicht zu schwierig, einen Vektor mit einer Kapazität zu erstellen, die ich denke. Wenn ich also ein Array an die Funktion übergeben kann, könnte es eine Konvertierung durchführen. Korrigiere mich, wenn ich falsch liege. – pengowen123

Antwort

3

Sieht aus wie ich das Problem gelöst habe. Ich habe die Python-Liste in ein C-Array umgewandelt und an die Rust-Funktion übergeben. Hier ist der Arbeitscode:

#[repr(C)] 
pub struct List_4 { 
    // Create a struct using #[repr(C)], will do the same in Python so it is shareable 
    array: [i32; 4] 
} 

#[no_mangle] 
pub extern fn function_array(list: List_4) -> List_4 { 
    // Return a new instance of List_4 
    List_4 { array: [1, 2, 3, 5] } 
} 

Python:

import ctypes # By using ctypes, and #[repr(C)], we use the same type 
       # of data in both languages, so it is possible to send stuff between them 

rust = cdll.LoadLibrary("target/debug/py_link.dll") # Import the Rust dll 

class List_4(ctypes.Structure): 
    # Similar to creating the struct in Rust 
    _fields_ = [("array", ctypes.ARRAY(ctypes.c_int32, 4))] 

rust.function_array.restype = List_4 # Set the function's return type to List_4 

def function_array(arr): 
    # For convenience, a function to convert a list to a C array, call the function, 
    # and convert its return value to a list 
    return list(
     rust.function_array(
      (ctypes.c_int * len(lst))(*lst) # Call the function after converting the list 
     ).array 
    ) 

# To use the function: 
>>> function_array([1, 2, 3]) 
[1, 2, 3, 5]