expose function from rust

  1. #[repr(C)]
  2. pub struct NativeVec {
  3. vec: *mut u32,
  4. vec_len: usize,
  5. vec_cap: usize,
  6. }
  7. #[no_mangle]
  8. pub extern "C" fn new_vec() -> *mut NativeVec {
  9. let v = vec![1_u32,2,3];
  10. // prevent running v's destructor so we are in complete control of the allocation
  11. // this is important
  12. let mut v = mem::ManuallyDrop::new(v);
  13. let nv = Box::new(NativeVec {
  14. vec: v.as_mut_ptr(),
  15. vec_len: v.len(),
  16. vec_cap: v.capacity(),
  17. });
  18. Box::into_raw(nv)
  19. }
  20. #[no_mangle]
  21. pub extern "C" fn mutate_vec(v: *mut NativeVec) {
  22. unsafe {
  23. let v = Box::from_raw(v);
  24. let v2 = Vec::from_raw_parts(v.vec, v.vec_len, v.vec_cap);
  25. println!("len {:?}", v2.len());
  26. println!("cap {:?}", v2.capacity());
  27. println!("first {:?}", v2[0]);
  28. println!("second {:?}", v2[1]);
  29. println!("third {:?}", v2[2]);
  30. drop(v2); // not nessery calling manually
  31. };
  32. }
  1. [package]
  2. name = "c_to_rust"
  3. version = "0.1.0"
  4. authors = ["Sean <xujihui1985@gmail.com>"]
  5. edition = "2018"
  6. build = "build.rs"
  7. # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
  8. [build-dependencies]
  9. cbindgen = "0.13.1"
  10. [lib]
  11. crate-type=["cdylib", "staticlib"]

cbindgen 是用来生成c 头文件为c代码用的

build.rs

  1. extern crate cbindgen;
  2. use std::env;
  3. use cbindgen::Language;
  4. fn main() {
  5. let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
  6. cbindgen::Builder::new()
  7. .with_crate(crate_dir)
  8. .with_language(Language::C)
  9. .generate()
  10. .expect("Unable to generate bindings")
  11. .write_to_file("target/debug/my_library.h");
  12. }

calling from c

  1. #include "my_library.h"
  2. #include <stdio.h>
  3. int main()
  4. {
  5. NativeVec* v = new_vec();
  6. printf("length of vec is %d\n", v->vec_len);
  7. for (int i = 0; i < v->vec_len; i++)
  8. {
  9. printf("vec value is is %d\n", *(v->vec + i));
  10. *(v->vec + i) = 123;
  11. }
  12. printf("addr %p\n", v->vec);
  13. mutate_vec(v);
  14. return 0;
  15. }
  1. gcc -o main.out main.c -I./target/debug -L./target/debug -lc_to_rust