#[repr(transparent)]pub struct UHandle<'a, T: ?Sized + 'a>(pub *mut *mut T, pub PhantomData<&'a T>);
Expand description
A handle from LabVIEW for the data.
A handle is a double pointer so the underlying data can be resized and moved.
Deref
is implemented for this type so you can access the data using *
but this can panic if the handle is invalid.
fn print_value(handle: UHandle<i32>) {
println!("{}", *handle);
}
If you want to handle the error you can use the UHandle::as_ref
or UHandle::as_ref_mut
method.
Tuple Fields§
§0: *mut *mut T
§1: PhantomData<&'a T>
Implementations§
Source§impl<T: ?Sized + LVCopy + 'static> UHandle<'_, T>
impl<T: ?Sized + LVCopy + 'static> UHandle<'_, T>
Sourcepub fn try_to_owned(&self) -> Result<OwnedUHandle<T>>
pub fn try_to_owned(&self) -> Result<OwnedUHandle<T>>
Try to create an owned handle from the current handle.
The owned handle will have its own handle to the data and will be responsible for freeing it.
§Errors
- If there is not enough memory to create the handle this may error.
- If the source handle is not valid this will error.
Source§impl<T: ?Sized + LVCopy + 'static> UHandle<'_, T>
impl<T: ?Sized + LVCopy + 'static> UHandle<'_, T>
Sourcepub unsafe fn clone_into_pointer(
&self,
other: *mut UHandle<'_, T>,
) -> Result<()>
pub unsafe fn clone_into_pointer( &self, other: *mut UHandle<'_, T>, ) -> Result<()>
Copy the contents of one handle into another.
If other points to a null value then this will allocate a handle for the contents.
The data in the handle must be 'static
or copy as this will only perform a shallow copy.
§Safety
- If the other pointer is invalid this may cause UB.
- If the other pointer points to null, you must wrap the value as an owned handle otherwise it will leak memory.
§Examples
§Allowed Types
use labview_interop::labview_layout;
use labview_interop::memory::{UHandle, OwnedUHandle};
use labview_interop::types::LStrHandle;
labview_layout! {
#[derive(Copy, Clone)]
struct ClusterWithNumbers {
float: f64,
int: i32
}
}
fn copy_handles(input: UHandle<ClusterWithNumbers>) {
let cluster = ClusterWithNumbers { float: 3.14, int: 42 };
let mut new_owned = OwnedUHandle::new(&cluster).unwrap();
unsafe {
let mut target_handle = new_owned.handle_to_inner();
input.clone_into_pointer(&mut target_handle).unwrap();
}
}
§Lifetime Guarantees - Fails with Sub-Handles
use labview_interop::labview_layout;
use labview_interop::memory::{UHandle, LvOwned};
use labview_interop::types::LStrHandle;
labview_layout! {
struct ClusterWithString<'a> {
string_handle: LStrHandle<'a>,
int: i32
}
}
fn copy_handles(input: UHandle<ClusterWithString>) {
let mut new_owned = LvOwned::<ClusterWithString>::new().unwrap();
unsafe {
let mut target_handle = new_owned.handle_to_inner();
input.clone_into_pointer(&mut target_handle).unwrap();
}
}
§Lifetime Guarantees - Fails with Owned Handle
use labview_interop::labview_layout;
use labview_interop::memory::{UHandle, LvOwned};
use labview_interop::types::LStrOwned;
labview_layout! {
struct ClusterWithString {
string_handle: LStrOwned,
int: i32
}
}
fn copy_handles(input: UHandle<ClusterWithString>, mut output: UHandle<ClusterWithString>) {
unsafe {
input.clone_into_pointer(&mut output).unwrap();
}
}
Source§impl<T: ?Sized> UHandle<'_, T>
impl<T: ?Sized> UHandle<'_, T>
Sourcepub unsafe fn as_ref(&self) -> Result<&T>
pub unsafe fn as_ref(&self) -> Result<&T>
Get a reference to the internal type. Errors if the pointer is null.
§Safety
This is a wrapper around pointer::as_ref
and so must follow its safety rules. Namely:
- When calling this method, you have to ensure that either the pointer is null or all of the following is true:
- The pointer must be properly aligned.
- It must be “dereferenceable” in the sense defined in [the module documentation].
- The pointer must point to an initialized instance of T.
- You must enforce Rust’s aliasing rules, since the returned lifetime ’a is arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. In particular, while this reference exists, the memory the pointer points to must not get mutated (except inside UnsafeCell).
Sourcepub unsafe fn as_ref_mut(&self) -> Result<&mut T>
pub unsafe fn as_ref_mut(&self) -> Result<&mut T>
Get a mutable reference to the internal type. Errors if handle contains a null.
§Safety
This method wraps the pointer::as_mut
method and so follows its safety rules which require all of the following is true:
- The pointer must be properly aligned.
- It must be “dereferenceable” in the sense defined in the module documentation.
- The pointer must point to an initialized instance of T.
- You must enforce Rust’s aliasing rules, since the returned lifetime ’a is arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. In particular, while this reference exists, the memory the pointer points to must not get accessed (read or written) through any other pointer.
Sourcepub fn valid(&self) -> bool
pub fn valid(&self) -> bool
Check the validity of the handle to ensure it wont panic later.
A valid handle is:
. Not Null. . Points to a pointer. . That pointer is in the LabVIEW memory zone.
The last 2 checks are done by LabVIEW and require the link
feature.
If the link
feature is not enabled then we just check it is not null.
§Panics/Safety
This will cause a segfault if the handle doesn’t point to a valid address.
Source§impl<const D: usize, T: NumericArrayResizable> UHandle<'_, LVArray<D, T>>
impl<const D: usize, T: NumericArrayResizable> UHandle<'_, LVArray<D, T>>
Sourcepub fn resize_array(&mut self, new_dims: LVArrayDims<D>) -> Result<()>
pub fn resize_array(&mut self, new_dims: LVArrayDims<D>) -> Result<()>
Resize the array to the new size.
Source§impl UHandle<'_, LStr>
Implement features that require a full string handle rather than just the LStr
type.
impl UHandle<'_, LStr>
Implement features that require a full string handle rather than just the LStr
type.
Requires the link feature.
Sourcepub fn set(&mut self, value: &[u8]) -> Result<()>
pub fn set(&mut self, value: &[u8]) -> Result<()>
Set the string as a binary value against the handle.
This function will resize the handle based on the size of the input value.
§Errors
- This will error if the string handle is invalid (likely a null pointer).
§Example
use labview_interop::types::{LVStatusCode, LStrHandle};
#[no_mangle]
pub extern "C" fn hello_world(mut string: LStrHandle) -> LVStatusCode {
let result = string.set(b"Hello World");
result.into()
}
Sourcepub fn set_str(&mut self, value: &str) -> Result<()>
pub fn set_str(&mut self, value: &str) -> Result<()>
Set string takes a Rust string and puts it into the LabVIEW String.
This is a two step process:
- Encode from Rust (UTF8) to LabVIEW encoding (based on system code page on Windows).
- Write this encoding into the LabVIEW string.
If the input is valid ASCII then no additional data copies are made. If not then this will allocate a new intermediate buffer to hold the decoded results before writing to the LabVIEW string.
Sourcepub fn set_str_with_encoding(
&mut self,
encoder: &'static Encoding,
value: &str,
) -> Result<()>
pub fn set_str_with_encoding( &mut self, encoder: &'static Encoding, value: &str, ) -> Result<()>
Set string with encoder takes a Rust string and puts it into the LabVIEW String.
This is a two step process:
- Encode from Rust (UTF8) to LabVIEW encoding with the provided encoder.
- Write this encoding into the LabVIEW string.
If the input is valid ASCII then no additional data copies are made. If not then this will allocate a new intermediate buffer to hold the decoded results before writing to the LabVIEW string.
The encoder should be an encoder provided by the encoding_rs crate.
Trait Implementations§
impl<'a, T: Eq + ?Sized + 'a> Eq for UHandle<'a, T>
impl<T: ?Sized> Send for UHandle<'_, T>
§Safety
- UHandle memory is managed by the Labview Memory Manager, which is thread safe