2017-01-04 3 views
1

Je peux appeler mon programme de test Rust avec des entiers en entrée et les gérer correctement, même sans référence à ctypes. Cependant, je n'arrive pas à obtenir une chaîne sans segfaulting dans Rust.Appel de rouille à partir de Python avec une chaîne dans les paramètres de la fonction

Voici mon test code Rust:

use std::env; 

#[no_mangle] 
pub extern fn helloworld(names: &str) { 
    println!("{}", names); 
    println!("helloworld..."); 
} 

#[no_mangle] 
pub extern fn ihelloworld(names: i32) { 
    println!("{}", names); 
    println!("ihelloworld..."); 
} 

ihelloworld fonctionne très bien. Mais je ne peux pas trouver un moyen d'obtenir une chaîne de Python dans Rust même si j'utilise ctypes.

Voici le code d'appel Python:

import sys, ctypes, os 
from ctypes import cdll 
from ctypes import c_char_p 
from ctypes import * 


if __name__ == "__main__": 
    directory = os.path.dirname(os.path.abspath(__file__)) 
    lib = cdll.LoadLibrary(os.path.join(directory, "target/release/libembeded.so")) 

    lib.ihelloworld(1) 
    lib.helloworld.argtypes = [c_char_p] 
    #lib.helloworld(str("test user")) 
    #lib.helloworld(u'test user') 
    lib.helloworld(c_char_p("test user")) 

    print("finished running!") 

La sortie est:

1 
ihelloworld... 
Segmentation fault (core dumped) 

La ihellowworld fonction de Rust fonctionne très bien, mais je ne peux pas sembler obtenir helloworld travail.

+2

Voir aussi [Rust Omnibus FFI] (http://jakegoulding.com/rust-ffi-omnibus/) et les * nombreuses * [questions existantes sur Rust + Python] (http: // stackoverflow. com/recherche? q =% 5Brust% 5D +% 5Bpython% 5D + est% 3Aq). – Shepmaster

+0

@Shepmaster Merci, j'ai regardé, je présume que Omnibus est à vous - c'est bon pour couvrir ces petits points que je n'arrive pas à trouver dans la documentation de Rust. – disruptive

Répondre

1

J'ai utilisé the Rust FFI Omnibus et maintenant mon code semble fonctionner correctement.

use std::env; 
use std::ffi::{CString, CStr}; 
use std::os::raw::c_char; 

#[no_mangle] 
pub extern "C" fn helloworld(names: *const c_char) { 

    unsafe { 
     let c_str = CStr::from_ptr(names).to_str().unwrap(); 
     println!("{:?}", c_str); 

    } 
    println!("helloworld..."); 

} 
1

La chaîne envoyée à partir de Python doit être représentée dans Rust en tant que CString à la place.