2015-06-15 21 views
5

Citi modülüyle Python'a aktarılması gereken bir Rust kütüphanesine sahibim. Amacım Vec<T>/i32'u argümanlar olarak alıp Python'dan döndüren Rust işlevlerini kullanmaktır. Şu anda, tamsayıları Rust işlevlerine geçirebilir ve listelerini/tam sayılarını döndürmelerini sağlayabilirim.Python listesini Pas işlevine geçir

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 

Pas: Geçerli kod İşte

Bir Pas işlevine argüman olarak bir Python liste geçiyor yardıma ihtiyacınız ne
#[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] } 
} 

. En iyi tahminim, bir liste yerine işlev için bir ctypes.ARRAY geçirmektir, ancak bir Python listesini bu türe dönüştürmeyi nasıl yapacağımı bilmiyorum.

Not: Rust kodunu this related question'dan denedim, ancak derlemeye çalıştığımda "gcc` başarısız oldu: çıkış kodu: 1" ve "hatalı reloc adresi" diyor.

+0

bu soruyu çarpmak mümkün mü? Artık kimse görmeyecek ve ben bu soruya cevap vermeyi tercih ediyorum, yeni bir tane değil. – pengowen123

+0

Evet, Windows'dayım. Bana haber verdiğiniz için teşekkür ederim, ya yapabilirdim, ama bir dizi kullanmak daha kolay olurdu. Ancak, bence kapasitemde bir vektör yapmak çok zor olmayacaktı, bu yüzden eğer bir diziyi fonksiyona geçirirsem, bir dönüşüm yapabilirdi. Yanlışsam düzelt. – pengowen123

cevap

3

Sorunu çözdüğüm anlaşılıyor. Python listesini bir C dizisine çevirdim ve bunu Pas işlevine ilettim. İşte çalışma kodu:

#[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]