From e4f07ffe2fd858083c138d44bce5aa24f34353b1 Mon Sep 17 00:00:00 2001 From: Nathan Eikermann Date: Wed, 2 Jun 2021 00:45:26 +0200 Subject: [PATCH] we can now read c style string arrays --- .gitignore | 1 + Cargo.toml | 7 ++++++- Makefile | 6 ++++++ build.rs | 14 ++++++++++++++ ctest/bindings.h | 6 ++++++ ctest/test.c | 15 +++++++++++++++ src/lib.rs | 30 +++++++++++++++++++++++++++++- 7 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 Makefile create mode 100644 build.rs create mode 100644 ctest/bindings.h create mode 100644 ctest/test.c diff --git a/.gitignore b/.gitignore index 96ef6c0..a75ff49 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target Cargo.lock +/ctest/test diff --git a/Cargo.toml b/Cargo.toml index ef3db03..5636ebb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,11 +4,16 @@ version = "0.1.0" authors = ["Nathan Eikermann "] description = "A rust library providing various utilities. To be used via FFI" edition = "2018" -#build = "build.rs" +build = "build.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +libc = "0.2" +ffi-convert = "0.5" + +[build-dependencies] +cbindgen = "0.19.0" [lib] crate-type = ["cdylib", "lib"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6898064 --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +DEBUG=target/debug/libmd_util_rs.so +FILE=ctest/test.c +OUTPUT=ctest/test +test: + gcc -o ${OUTPUT} ${FILE} -Isrc -L. -l:${DEBUG} + ./ctest/test diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..4bdeb9a --- /dev/null +++ b/build.rs @@ -0,0 +1,14 @@ +extern crate cbindgen; + +use std::env; + +fn main() { + let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + + cbindgen::Builder::new() + .with_crate(crate_dir) + .with_language(cbindgen::Language::C) + .generate() + .expect("Unable to generate bindings") + .write_to_file("./ctest/bindings.h"); +} diff --git a/ctest/bindings.h b/ctest/bindings.h new file mode 100644 index 0000000..153368c --- /dev/null +++ b/ctest/bindings.h @@ -0,0 +1,6 @@ +#include +#include +#include +#include + +void files_exist(const char *const *f, size_t len); diff --git a/ctest/test.c b/ctest/test.c new file mode 100644 index 0000000..d4682a2 --- /dev/null +++ b/ctest/test.c @@ -0,0 +1,15 @@ +#include +#include +#include +#include + +extern void files_exist(const char *const *f, size_t len); + +int main(int argc, char const* argv[]) +{ + const char *a[2]; + a[0] = "Hello"; + a[1] = "World!"; + files_exist(a, 2); + return 0; +} diff --git a/src/lib.rs b/src/lib.rs index 31e1bb2..27b0f27 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,35 @@ +extern crate ffi_convert; +extern crate libc; + +use ffi_convert::{AsRust, CReprOf, CStringArray}; +use libc::c_char; +use libc::size_t; +//use std::ffi::CStr; +//use std::ffi::CString; +use std::path::Path; +//use std::slice; + +fn file_exists(file_path: &str) -> bool { + return Path::new(file_path).is_file(); +} + +#[no_mangle] +pub extern "C" fn files_exist(f: *const *const c_char, len: size_t) -> () { + let files = unsafe { + assert!(!f.is_null()); + CStringArray { data: f, size: len } + }; + + println!("{:?}", files.as_rust().unwrap()); + std::mem::forget(files); +} + #[cfg(test)] mod tests { + use super::*; + #[test] fn it_works() { - assert_eq!(2 + 2, 4); + assert_eq!(file_exists("/home/nathan/Downloads/cert.sh"), true); } }