This commit is contained in:
Maurice
2023-10-17 19:00:03 +02:00
commit 828e08c6ce
8 changed files with 564 additions and 0 deletions

87
src/lib.rs Normal file
View File

@@ -0,0 +1,87 @@
use std::{slice, thread};
use async_channel::{Sender, Receiver, unbounded};
use async_io::block_on;
use async_lock::{OnceCell, RwLock};
type Callback = extern "C" fn (ByteArray);
static CHANNEL: OnceCell<(Sender<Vec<u8>>, Receiver<Vec<u8>>)> = OnceCell::new();
static CALLBACK: RwLock<Option<Callback>> = RwLock::new(None);
fn get_channel() -> &'static (Sender<Vec<u8>>, Receiver<Vec<u8>>) {
CHANNEL.get_or_init_blocking(|| {
println!("Initialized channel");
unbounded()
})
}
fn get_sender() -> &'static Sender<Vec<u8>> {
&get_channel().0
}
fn get_receiver() -> &'static Receiver<Vec<u8>> {
&get_channel().1
}
#[repr(C)]
pub struct ByteArray {
data: *const u8,
length: usize
}
impl From<Vec<u8>> for ByteArray {
fn from(value: Vec<u8>) -> Self {
ByteArray { data: value.as_ptr(), length: value.len() }
}
}
#[no_mangle]
pub extern "C" fn register_callback(cb: Callback) {
block_on(async {
let mut writer = CALLBACK.write().await;
*writer = Some(cb);
});
}
#[no_mangle]
pub extern "C" fn start_listening() {
let receiver = get_receiver().clone();
thread::spawn(move|| {
block_on(async {
println!("Start listening for received events");
loop {
let next = receiver.recv().await;
if let Ok(data) = next {
println!("Received data: {:?}", data);
let reader = CALLBACK.read().await;
if reader.is_some() {
println!("Calling callback");
let cb = reader.unwrap();
let bytes = ByteArray::from(data);
cb(bytes);
} else {
println!("No callback");
}
}
}
})
});
}
#[no_mangle]
pub extern "C" fn send(data: *const u8, length: usize) {
let byte_slice = unsafe {
assert!(!data.is_null());
slice::from_raw_parts(data, length)
};
get_sender().send_blocking(byte_slice.to_vec()).unwrap();
println!("Received {} bytes, array: {:?}", length, byte_slice);
}
#[no_mangle]
pub extern "C" fn receive() -> ByteArray {
let data = get_receiver().recv_blocking().unwrap();
ByteArray::from(data)
}