-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Current Approach - Read String using LabVIEW's MoveBlock functionality (before closing reference)
Here is the VI that reads a cstring from a memory location:
The MoveBlock function is exported by the LabVIEW executable app:
After we're done reading the data, we close the reference:
Different Approach - Use CLFN to Read String, but also pass string reference (so we can close reference)
A slightly different approach to reading string data from Rust is to have the CLFN read the string data (instead of just getting the address of the data and reading it with the Memory Manager). This is nice, because we can rely on LabVIEW's built in feature for reading a cstring, however, it means that we must also pass out the string's address, separately, so that we can ask Rust to deallocate/free the string after LabVIEW has read the data.
That looks something like this:
Notes:
- there's an additional parameter
string_ptr: *mut c_void,which is how we will obtain the string pointer (in note 2 below).- right before we return, we will write the return string's address to the
string_ptrparameter that was passed in -->unsafe { *(string_ptr as *mut *mut c_char) = raw_string; }
// return a toml string from a Document
#[allow(dead_code)]
#[no_mangle]
pub extern "C" fn toml_edit_doc_to_string (
doc: *mut c_void,
string_ptr: *mut c_void,
) -> *mut c_char {
let doc = unsafe { &mut *(doc as *mut Document) };
let toml_str = match Document::to_string(doc) {
toml_str => toml_str,
};
let raw_string = match CString::new(toml_str).unwrap().into_raw() {
ptr if ptr.is_null() => {
println!("Unable to allocate memory for string");
return CString::new("").unwrap().into_raw();
},
ptr => ptr,
};
// write raw_string's address as the value stored in string_ptr
unsafe { *(string_ptr as *mut *mut c_char) = raw_string; }
return raw_string;
}When we call this from LabVIEW, we can read the return string using the built in CLFN's C String Pointer format for strings.
And, we will ALSO get the address of the string as an integer that we can pass back to Rust to deallocate/free, using the cstring_free_memory() function shown below:
// exported function that frees the memory allocated for a string
// this *must* be called for every string returned from a function in this library
#[no_mangle]
pub extern "C" fn cstring_free_memory(s: *mut c_char) {
unsafe {
if s.is_null() {
return;
}
CString::from_raw(s)
};
}





