From ce78aa2a93b33ae219d13079c476af8734cb0fea Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Thu, 30 Jan 2020 21:03:38 +0800 Subject: [PATCH] add c_export --- c_export/Cargo.toml | 14 ++++++++++++++ c_export/README.md | 29 +++++++++++++++++++++++++++++ c_export/call_in_c.c | 9 +++++++++ c_export/call_in_node.js | 8 ++++++++ c_export/call_in_python.py | 5 +++++ c_export/src/lib.rs | 17 +++++++++++++++++ 6 files changed, 82 insertions(+) create mode 100644 c_export/Cargo.toml create mode 100644 c_export/README.md create mode 100644 c_export/call_in_c.c create mode 100644 c_export/call_in_node.js create mode 100644 c_export/call_in_python.py create mode 100644 c_export/src/lib.rs diff --git a/c_export/Cargo.toml b/c_export/Cargo.toml new file mode 100644 index 0000000..ccc1ea5 --- /dev/null +++ b/c_export/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "c_export" +version = "0.1.0" +authors = ["Hatter Jiang "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +name = "stringtools" +crate-type = ["dylib"] + +[dependencies] +libc = "0.2.60" diff --git a/c_export/README.md b/c_export/README.md new file mode 100644 index 0000000..c13bec3 --- /dev/null +++ b/c_export/README.md @@ -0,0 +1,29 @@ + +Rust libray build: +``` +cargo build +``` + + +Python test: +``` +python call_in_python.py +``` + + +C test: +``` +gcc call_in_c.c -L target/debug/ -lstringtools +``` + + +NodeJS test: +``` +npm install ffi +node call_in_node.js +``` + + +Reference: +http://siciarz.net/24-days-of-rust-calling-rust-from-other-languages/ + diff --git a/c_export/call_in_c.c b/c_export/call_in_c.c new file mode 100644 index 0000000..790277b --- /dev/null +++ b/c_export/call_in_c.c @@ -0,0 +1,9 @@ +#include +#include + +int32_t count_substrings(const char* value, const char* substr); + +int main() { + printf("%d\n", count_substrings("banana", "na")); + return 0; +} diff --git a/c_export/call_in_node.js b/c_export/call_in_node.js new file mode 100644 index 0000000..fcfc504 --- /dev/null +++ b/c_export/call_in_node.js @@ -0,0 +1,8 @@ +var ffi = require('ffi'); + +var stringtools = ffi.Library('target/debug/libstringtools.dylib', { + 'count_substrings': ['int', ['string', 'string']] +}); + +console.log(stringtools.count_substrings("banana", "na")); + diff --git a/c_export/call_in_python.py b/c_export/call_in_python.py new file mode 100644 index 0000000..9f3db5c --- /dev/null +++ b/c_export/call_in_python.py @@ -0,0 +1,5 @@ +import ctypes + +stringtools = ctypes.CDLL("target/debug/libstringtools.dylib") +print(stringtools.count_substrings(b"banana", b"na")) + diff --git a/c_export/src/lib.rs b/c_export/src/lib.rs new file mode 100644 index 0000000..0a716d6 --- /dev/null +++ b/c_export/src/lib.rs @@ -0,0 +1,17 @@ +extern crate libc; + +use std::ffi::CStr; +use libc::c_char; + +#[no_mangle] +pub extern "C" fn count_substrings(value: *const c_char, substr: *const c_char) -> i32 { + let c_value = unsafe { CStr::from_ptr(value) }; + let c_substr = unsafe { CStr::from_ptr(substr) }; + match c_value.to_str() { + Ok(value) => match c_substr.to_str() { + Ok(substr) => value.match_indices(substr).count() as i32, + Err(_) => -1, + }, + Err(_) => -1, + } +}