Use bindgen for rust bindings

This commit is contained in:
Greg Shuflin 2021-02-28 12:23:30 -08:00
parent cece963e91
commit e8099fc681
5 changed files with 64 additions and 23 deletions

View File

@ -12,3 +12,6 @@ crate-type = ["staticlib"]
[dependencies]
libc = "0.2"
getopts = "0.2"
[build-dependencies]
bindgen = "0.53.1"

32
build.rs Normal file
View File

@ -0,0 +1,32 @@
extern crate bindgen;
use std::env;
use std::path::PathBuf;
fn main() {
// Tell cargo to invalidate the built crate whenever the wrapper changes
println!("cargo:rerun-if-changed=radio.h");
// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
let bindings = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header("radio.h")
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.whitelist_type("radio_device_t")
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings for radio.h");
// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}

View File

@ -29,6 +29,8 @@
//
// Check for compatible radio model.
//
#include <stdio.h>
int radio_is_compatible(const char *ident);
//

View File

@ -1,7 +1,12 @@
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
use libc::{c_int, c_char};
use getopts::Options;
use std::process::exit;
mod radio;
const COPYRIGHT: &'static str = "Copyright (C) 2018 Serge Vakulenko KK6ABQ";

View File

@ -2,22 +2,21 @@ use std::ffi::CString;
use libc::{c_char, c_int};
use std::os::unix::io::AsRawFd;
#[repr(C)]
pub struct RadioDeviceT { _private: [u8; 0] }
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
extern {
fn radio_connect() -> *const RadioDeviceT;
fn radio_connect() -> *const radio_device_t;
fn radio_download(device: *const RadioDeviceT);
fn radio_upload(device: *const RadioDeviceT, cont_flag: c_int);
fn radio_download(device: *const radio_device_t);
fn radio_upload(device: *const radio_device_t, cont_flag: c_int);
fn radio_list_c();
fn radio_verify_config(device: *const RadioDeviceT);
fn radio_print_version(device: *const RadioDeviceT, stdout: *const libc::FILE);
fn radio_print_config(device: *const RadioDeviceT, file: *const libc::FILE, verbose: c_int);
fn radio_read_image(filename: *const c_char) -> *const RadioDeviceT;
fn radio_save_image(device: *const RadioDeviceT, filename: *const c_char);
fn radio_parse_config(device: *const RadioDeviceT, filename: *const c_char);
fn radio_write_csv(device: *const RadioDeviceT, filename: *const c_char);
fn radio_verify_config(device: *const radio_device_t);
fn radio_print_version(device: *const radio_device_t, stdout: *const libc::FILE);
fn radio_print_config(device: *const radio_device_t, file: *const libc::FILE, verbose: c_int);
fn radio_read_image(filename: *const c_char) -> *const radio_device_t;
fn radio_save_image(device: *const radio_device_t, filename: *const c_char);
fn radio_parse_config(device: *const radio_device_t, filename: *const c_char);
fn radio_write_csv(device: *const radio_device_t, filename: *const c_char);
fn dfu_reboot();
fn dfu_close();
@ -27,7 +26,7 @@ extern {
/// Connect to the radio via the serial port.
/// Identify the type of device.
pub fn connect() -> *const RadioDeviceT {
pub fn connect() -> *const radio_device_t {
unsafe {
radio_connect()
}
@ -47,14 +46,14 @@ pub fn disconnect() {
}
/// Read firmware image from the device
pub fn download(device: *const RadioDeviceT) {
pub fn download(device: *const radio_device_t) {
unsafe {
radio_download(device)
}
}
/// Write firmware image to the device.
pub fn upload(device: *const RadioDeviceT, cont_flag: c_int) {
pub fn upload(device: *const radio_device_t, cont_flag: c_int) {
unsafe {
radio_upload(device, cont_flag)
}
@ -69,14 +68,14 @@ pub fn list() {
}
/// Check the configuration.
pub fn verify_config(device: *const RadioDeviceT) {
pub fn verify_config(device: *const radio_device_t) {
unsafe {
radio_verify_config(device);
}
}
/// Read firmware image from the binary file.
pub fn read_image(filename: &str) -> *const RadioDeviceT {
pub fn read_image(filename: &str) -> *const radio_device_t {
let filename = CString::new(filename.to_string()).unwrap();
unsafe {
radio_read_image(filename.as_ptr())
@ -84,7 +83,7 @@ pub fn read_image(filename: &str) -> *const RadioDeviceT {
}
/// Save firmware image to the binary file.
pub fn save_image(device: *const RadioDeviceT, filename: &str) {
pub fn save_image(device: *const radio_device_t, filename: &str) {
let filename = CString::new(filename.to_string()).unwrap();
unsafe {
radio_save_image(device, filename.as_ptr())
@ -92,7 +91,7 @@ pub fn save_image(device: *const RadioDeviceT, filename: &str) {
}
/// Read the configuration from text file, and modify the firmware.
pub fn parse_config(device: *const RadioDeviceT, filename: &str) {
pub fn parse_config(device: *const radio_device_t, filename: &str) {
let filename = CString::new(filename.to_string()).unwrap();
unsafe {
radio_parse_config(device, filename.as_ptr())
@ -100,7 +99,7 @@ pub fn parse_config(device: *const RadioDeviceT, filename: &str) {
}
/// Print full information about the device configuration.
pub fn print_config(device: *const RadioDeviceT, filename: &str) {
pub fn print_config(device: *const radio_device_t, filename: &str) {
let file = std::fs::File::create(filename).unwrap();
let fd = file.as_raw_fd();
let mode = CString::new("w").unwrap();
@ -111,7 +110,7 @@ pub fn print_config(device: *const RadioDeviceT, filename: &str) {
}
}
pub fn print_config_to_stdout(device: *const RadioDeviceT) {
pub fn print_config_to_stdout(device: *const radio_device_t) {
let mode = CString::new("w").unwrap();
unsafe {
let stdout = libc::fdopen(libc::STDOUT_FILENO, mode.as_ptr());
@ -125,7 +124,7 @@ pub fn print_config_to_stdout(device: *const RadioDeviceT) {
}
/// Print generic information about the device.
pub fn print_version(device: *const RadioDeviceT) {
pub fn print_version(device: *const radio_device_t) {
let mode = CString::new("w").unwrap();
unsafe {
radio_print_version(device, libc::fdopen(libc::STDOUT_FILENO, mode.as_ptr()));
@ -133,7 +132,7 @@ pub fn print_version(device: *const RadioDeviceT) {
}
/// Update CSV contacts database.
pub fn write_csv(device: *const RadioDeviceT, filename: &str) {
pub fn write_csv(device: *const radio_device_t, filename: &str) {
let filename = CString::new(filename.to_string()).unwrap();
unsafe {
radio_write_csv(device, filename.as_ptr());