From c072e9cfa9266d357017fc35bb20143626e3b949 Mon Sep 17 00:00:00 2001 From: dece Date: Sat, 9 May 2020 18:58:55 +0200 Subject: [PATCH] ffi: make name_hashes mod available --- Cargo.lock | 1 + Cargo.toml | 1 + ffi_tests.py | 15 ++++++++++++--- src/name_hashes.rs | 25 +++++++++++++++++++++++-- src/utils/ffi.rs | 12 ++++++++++++ 5 files changed, 49 insertions(+), 5 deletions(-) mode change 100644 => 100755 ffi_tests.py create mode 100644 src/utils/ffi.rs diff --git a/Cargo.lock b/Cargo.lock index 553991b..7243817 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,6 +183,7 @@ dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", "nom 5.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 40cc458..8e4737d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ name = "ironring" clap = "2.33" encoding_rs = "0.8" flate2 = "1.0" +libc = "0.2" nom = "5" num-bigint = "0.2" num-traits = "0.2" diff --git a/ffi_tests.py b/ffi_tests.py old mode 100644 new mode 100755 index 5b1f52a..bd596aa --- a/ffi_tests.py +++ b/ffi_tests.py @@ -1,8 +1,17 @@ #!/usr/bin/env python3 """Import hash from the rir dynamic lib.""" +import ctypes import sys -from ctypes import cdll -lib = cdll.LoadLibrary(sys.argv[1]) -#print(lib.name_hashes.hash("/chr/c0000.anibnd.dcx")) + +lib = ctypes.cdll.LoadLibrary(sys.argv[1]) + +s = ctypes.c_char_p(b"/chr/c0000.anibnd.dcx") +lib.nam_hash.restype = ctypes.c_uint32 +h = lib.nam_hash(s) +print(hex(h)) + +lib.nam_hash_as_string.restype = ctypes.c_char_p +h_str = lib.nam_hash_as_string(h) +print(h_str) diff --git a/src/name_hashes.rs b/src/name_hashes.rs index f937e89..b59bb31 100644 --- a/src/name_hashes.rs +++ b/src/name_hashes.rs @@ -1,5 +1,5 @@ use std::collections::HashMap; -use std::fs::File; +use std::fs; use std::io::{BufRead, BufReader, Error}; use num_bigint::BigUint; @@ -21,13 +21,18 @@ pub fn hash_as_string(h: u32) -> String { format!("{:08X}", h) } +//#[no_mangle] +//pub extern "C" fn nam_hash_as_string(h: u32) -> *mut libc::c_char { +// hash_as_string(h) +//} + /// Load a namelist file into a map. /// /// Format for the input file should be the following for every line: /// CAFECAFE: /chr/whatever.ext pub fn load_name_map(path: &str) -> Result, Error> { let mut names = HashMap::new(); - let namefile = File::open(path)?; + let namefile = fs::File::open(path)?; for line_ in BufReader::new(namefile).lines() { if let Ok(line) = line_ { let (hash, name) = line.split_at(8); @@ -37,6 +42,22 @@ pub fn load_name_map(path: &str) -> Result, Error> { Ok(names) } +mod rir_ffi { + use std::ffi; + use super::*; + + #[no_mangle] + pub extern "C" fn nam_hash(s: *const libc::c_char) -> u32 { + let c_s = unsafe { assert!(!s.is_null()); ffi::CStr::from_ptr(s) }; + hash(c_s.to_str().unwrap()) + } + + #[no_mangle] + pub extern "C" fn nam_hash_as_string(h: u32) -> *mut libc::c_char { + ffi::CString::new(hash_as_string(h)).unwrap().into_raw() + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/utils/ffi.rs b/src/utils/ffi.rs new file mode 100644 index 0000000..87dd075 --- /dev/null +++ b/src/utils/ffi.rs @@ -0,0 +1,12 @@ +use std::ffi; + +/// Free a String owned by librir. +#[no_mangle] +pub extern "C" fn ffi_free_string(s: *mut libc::c_char) { + unsafe { + if s.is_null() { + return; + } + ffi::CString::from_raw(s) + } +}