C en Rust

Entradas Archivos Wallpaper ASCCI Problemas

Este es un pequeño resumen de como usar codigo de C existente en proyectos de Rust.

build.rs

Este es un pequeño programa que se encargara de compilar el codigo de C para despues añadirlo a el codigo de Rust.

En este caso especificamos el codigo y la compilacion

build.rs

extern crate cc; //Importamos la libreria que nos ayda a compilar

fn main() {
    cc::Build::new()
        .file("src/contar.c") // Especificamos el archivo
        .compile("libcontar.a"); // especificamos la salida
}

Y añadimos la dependencia de el script bajo esta seccion en el archivo Cargo.toml Cargo.toml

[build-dependencies]
cc = { version = "1.0", features = ["parallel"] }

Y asi ya podemos acceder a las funciones que tenemos en nuestros archivos, pero hay que declararla primero

extern "C" {
    fn funcion(arg: type) -> type;
}

Donde para acceder a los tipos de c se tiene que usar la siguiente importacion:

use std::ffi::{tipo};

Y los tipos estan llamados:

Algo que note fue que para pasar un String de rust a una funcion que necesecite un *char se requiere de la siquiente funcion Donde si la funcion usa un **char * ** en Rust se tiene que declarar como *const c_char

#[no_mangle]
pub extern "C" fn create_string(val: Option<&str>) -> *const c_char {
    match val {
        Some(val) => {
            let c_string = CString::new(val).expect("CString::new failed");
            c_string.into_raw() // Move ownership to C
        }
        None => CString::new("No value")
            .expect("CString::new failed")
            .into_raw(),
    }
}

Si se tienen funciones que requieren structuras especificas estas se tienen que declarar tanto en C como en Rust

Rust

#[repr(C)]
pub struct Raices {
    pub positivas: i32,
    pub negativas: i32,
}

C

typedef struct {
  int positivas;
  int negativas;
}Raices;

Y finalmente para ejecutar las funciones se requiere usar la funcion unsafe

unsafe{funcion()}