2017-09-25 6 views
2

J'essaye de créer et retourner une structure C++. Je reçois actuellement une erreur cannot move out of dereference of raw pointer lorsque j'essaie de compiler. Une idée de comment je peux faire ce travail?Comment créer et renvoyer une structure C++ à partir de Rust FFI?

#![allow(non_snake_case)] 
#![allow(unused_variables)] 

extern crate octh; 

// https://thefullsnack.com/en/string-ffi-rust.html 
use std::ffi::CString; 

#[no_mangle] 
pub unsafe extern "C" fn Ghelloworld(
    shl: *const octh::root::octave::dynamic_library, 
    relative: bool, 
) -> *mut octh::root::octave_dld_function { 
    let name = CString::new("helloworld").unwrap(); 
    let pname = name.as_ptr() as *const octh::root::std::string; 
    std::mem::forget(pname); 

    let doc = CString::new("Hello World Help String").unwrap(); 
    let pdoc = doc.as_ptr() as *const octh::root::std::string; 
    std::mem::forget(pdoc); 

    return octh::root::octave_dld_function_create(Some(Fhelloworld), shl, pname, pdoc); 
} 

pub unsafe extern "C" fn Fhelloworld(
    args: *const octh::root::octave_value_list, 
    nargout: ::std::os::raw::c_int, 
) -> octh::root::octave_value_list { 
    let list: *mut octh::root::octave_value_list = ::std::ptr::null_mut(); 
    octh::root::octave_value_list_new(list); 
    std::mem::forget(list); 
    return *list; 
} 

Répondre

6

Je suis en train de créer et retourner une struct C++

Vous ne pouvez pas; C++ (comme Rust) n'a pas d'ABI stable et défini. Il n'y a aucun moyen dans Rust de spécifier qu'une structure a repr(C++), donc vous ne pouvez pas créer une telle structure, et encore moins la retourner.

Le seul ABI est celui présenté par C. Vous peut définir struct stable repr(C) pour pouvoir les retourner directement:

extern crate libc; 

use std::ptr; 

#[repr(C)] 
pub struct ValueList { 
    id: libc::int32_t, 
} 

#[no_mangle] 
pub extern "C" fn hello_world() -> ValueList { 
    let list_ptr = ::std::ptr::null_mut(); 
    // untested, will cause segfault unless list_ptr is set 
    unsafe { ptr::read(list_ptr) } 
} 

Cette méthode est très suspecte cependant; Normalement, vous verriez comme

#[no_mangle] 
pub extern "C" fn hello_world() -> ValueList { 
    unsafe { 
     let mut list = mem::uninitialized(); 
     list_initialize(&mut list); 
     list 
    } 
} 

Voir aussi:


Je vous invite à lire mon Rust FFI Omnibus.

+1

Note: C++ * a aussi un C FFI, et donc toute classe/structure C++ compatible avec sa contrepartie C serait utilisable à partir de Rust comme à partir de C. –

+0

Merci @Shepmaster. Il compile maintenant. Ça fonctionne peut-être, mais mon monde d'Octave n'est pas encore, donc je ne suis pas sûr à 100%. https://github.com/ctaggart/octh_examples/blob/master/src/lib.rs –

+0

@CameronTaggart Je ne suis pas sûr, mais vous devriez empêcher le dénigrement de nom sur toutes les fonctions. Un '# [no_mangle]' ne manque-t-il pas dans 'Fhelloworld'? –