Closed chaoxi24 closed 3 years ago
Hello, I added a the most basic example i could come up with here : https://github.com/elast0ny/shared_memory-rs/blob/master/examples/basic.rs
It doesn't use any locking and simply increments a u8 that lives in shared memory.
Your issue with putting a string inside the shared memory is a bit more complicated to do properly & safely.
If you ignore all the safety concerns, you can do something like :
// Get pointer to the shared memory
let raw_ptr = shmem.as_ptr();
unsafe {
// The string is stored as [len:u32][data]
let str_len = raw_ptr as *mut u32;
// Create slice with the rest of the shmem
let str_data = std::slice::from_raw_parts_mut(
raw_ptr.add(std::mem::size_of::<u32>()),
shmem.len() - std::mem::size_of::<u32>()
);
if shmem.is_owner() {
let my_str = "asdfg";
// Copy our string characters into the shmem
str_data[..my_str.len()].copy_from_slice(my_str.as_bytes());
// Set the len
*str_len = my_str.len() as u32;
info!("Initialized string '{}' in shmem !", &my_str);
// Keep shmem alive for another 5 seconds
std::thread::sleep(std::time::Duration::from_secs(5));
} else {
// Wait until len has been set
while std::ptr::read_volatile(str_len) == 0 {}
// Assume the length is valid and shmem contains valid utf8
let shared_str = std::str::from_utf8_unchecked(&str_data[..std::ptr::read_volatile(str_len) as usize]);
info!("Read string '{}' from shared memory !", shared_str);
}
}
Thank you. I used a simpler solution to write strings.
fn main() {
let t = "asdfg".to_string();
unsafe {
cfm_set("T1", t.as_ptr(), t.len());
}
let (tx, rx) = std::sync::mpsc::channel();
let t: u32 = rx.recv().unwrap();
}
unsafe fn cfm_set(name: &'static str, ptr: *const u8, size: usize) {
extern "system" {
fn OpenFileMappingW(hFile: u32, dwFlags: bool, lpLibFileName: *const u16) -> u32;
fn MapViewOfFile(a: u32, b: u32, c: u32, d: u32, e: usize) -> u64;
fn UnmapViewOfFile(e: u64) -> u32;
fn RtlMoveMemory(a: u64, b: *const u8, c: usize);
fn CreateFileMappingW(a: i64, b: u32, c: u32, d: u32, e: u32, Name: *const u16) -> u32;
}
let sz = size as u32;
let nm: Vec<u16> = name.encode_utf16().chain(Some(0)).collect();
let cf = CreateFileMappingW(-1, 0, 4, sz >> 16 >> 16, sz & 0xffffffff, nm.as_ptr());
let mf = MapViewOfFile(cf, 2, 0, 0, 0);
RtlMoveMemory(mf, ptr, size);
UnmapViewOfFile(mf);
}
Can you provide a simple example that does not involve other packages? For example, save the string-"asdfg" to the shared memory named "T1". Yes, this is also my requirement, but I have read the two examples for a long time and don't know how to achieve my goal.