Skip to content

Commit 5c8352e

Browse files
committed
Add extern "C" get/free methods
1 parent 5bddc1f commit 5c8352e

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

src/rust/corelib/src/lib.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,29 @@ extern crate lmdb_sys;
33
extern crate sqlite_sys;
44

55
use libc::*;
6+
use std::ffi::CString;
7+
8+
#[no_mangle]
9+
pub extern "C" fn native_versions_get() -> *mut c_char {
10+
let s = format!("LMDB: {}\nBlosc: {}\nSQLite: {}", lmdb_version(), blosc_version(), sqlite_version());
11+
let cs = CString::new(s).unwrap();
12+
cs.into_raw()
13+
}
14+
15+
#[no_mangle]
16+
pub extern "C" fn native_versions_free(c: *mut c_char) {
17+
if c.is_null() {
18+
return;
19+
}
20+
// CString is dropped automatically when does out of scope
21+
unsafe { CString::from_raw(c); }
22+
23+
// Print diagnostics in debug build
24+
if cfg!(debug_assertions) {
25+
println!("Rust string is dropped");
26+
}
27+
}
28+
629

730
pub fn lmdb_version() -> String {
831
unsafe {
@@ -30,6 +53,17 @@ pub fn sqlite_version() -> String {
3053

3154
#[cfg(test)]
3255
mod tests {
56+
#[test]
57+
fn native_versions_get_works() {
58+
unsafe{
59+
let nv = super::native_versions_get();
60+
let cs = std::ffi::CString::from_raw(nv);
61+
assert_eq!(cs.to_str().unwrap(), "LMDB: 0.9.70\nBlosc: 1.15.2.dev\nSQLite: 3.29.0");
62+
std::mem::forget(cs);
63+
super::native_versions_free(nv);
64+
}
65+
}
66+
3367
#[test]
3468
fn lmdb_works() {
3569
assert_eq!(super::lmdb_version(), "0.9.70");

src/rust/sandbox/src/main.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
extern crate corelib;
22

33
fn main() -> () {
4-
println!("LMDB: {}", corelib::lmdb_version());
5-
println!("Blosc: {}", corelib::blosc_version());
6-
println!("SQLite: {}", corelib::sqlite_version());
4+
unsafe{
5+
let nv = corelib::native_versions_get();
6+
let cs = std::ffi::CString::from_raw(nv);
7+
println!("{}", cs.to_str().unwrap());
8+
std::mem::forget(cs); // Do not drop, we need return it back to destructor to simulate desired behavior
9+
corelib::native_versions_free(nv);
10+
}
711
}

0 commit comments

Comments
 (0)