diff --git a/README.md b/README.md index 572f7e9..d207c63 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,10 @@ Some extra steps are required to run the `query_version` example. Here I will on After cloning the repository or adding the crate to you Cargo.toml you must add Vimba's library directory to your LD_LIBRARY_PATH so that the example can link at runtime with the libVmbC.so: ``` Bash -export LD_LIBRARY_PATH=/opt/VimbaX_2025-2/api/lib +export LD_LIBRARY_PATH=/opt/VimbaX_2025-3/api/lib +note that the path may be different depending on the version of Vimba you have downloaded. +As of writing, the latest available version is VimbaX_2025-3. +Corresponding changes will have to be made to the `wrapper.h` and `build.rs` files to reflect your version ``` Now you can run the `query_version` example: diff --git a/build.rs b/build.rs index 119f368..17ed9b5 100644 --- a/build.rs +++ b/build.rs @@ -2,12 +2,12 @@ use std::env; use std::path::PathBuf; fn main() { - println!("cargo:rustc-link-search=/opt/VimbaX_2025-2/api/lib"); + println!("cargo:rustc-link-search=/opt/VimbaX_2025-3/api/lib"); println!("cargo:rustc-link-lib=VmbC"); unsafe { std::env::set_var( "BINDGEN_EXTRA_CLANG_ARGS", - "-I\"/opt/VimbaX_2025-2/api/include\"", + "-I\"/opt/VimbaX_2025-3/api/include\"", ); }; diff --git a/examples/list_tl_layers.rs b/examples/list_tl_layers.rs index a1dbdcb..3cd4bc4 100644 --- a/examples/list_tl_layers.rs +++ b/examples/list_tl_layers.rs @@ -1,7 +1,7 @@ use vimba_rs::api::{startup, transport_layers_list, shutdown}; fn main() { - match startup(Some("/opt/VimbaX_2025-2/cti/VimbaUSBTL.cti")) { + match startup(Some("/opt/VimbaX_2025-3/cti/VimbaUSBTL.cti")) { Ok(()) => { println!("Successfully started api") } diff --git a/src/api.rs b/src/api.rs index 1aa9a89..290c387 100644 --- a/src/api.rs +++ b/src/api.rs @@ -1,8 +1,9 @@ use super::{error::*, ffi::*, utils::*}; use std::{ - ffi, + ffi::{self, CStr, CString, c_char, c_double, c_void}, mem::{self, MaybeUninit}, ptr, + os::raw, }; use strum::FromRepr; @@ -88,6 +89,17 @@ impl CameraHandle { } } +pub type VmbFrameCallback = Option< + extern "C" fn( + handle: VmbHandle_t, + frame: *mut VmbFrame, + ) +>; + +// --------------------------------------------------------------- +// API Version +// --------------------------------------------------------------- + pub fn vmb_version_query() -> VmbResult { let mut version_raw = VmbVersionInfo_t { major: 0, @@ -110,6 +122,25 @@ pub fn vmb_version_query() -> VmbResult { }) } +// --------------------------------------------------------------- +// API Initialization +// --------------------------------------------------------------- + +#[derive(Debug, Clone)] +pub struct CameraInfo { + pub id: String, + pub extended_id: String, + pub camera_name: String, + pub model_name: String, + pub serial_number: String, + pub transport_layer_handle: TransportLayerHandle, + pub interface_handle: InterfaceHandle, + pub local_device_handle: LocalDeviceHandle, + pub stream_handles: StreamHandles, + pub stream_count: u32, + pub access: AccessMode, +} + pub fn startup(path_config: Option<&str>) -> VmbResult<()> { let path = path_config.unwrap_or("/opt/VimbaX-2025_2/cti/VimbaUSBTL.cti"); @@ -124,6 +155,10 @@ pub fn shutdown() { } } +// --------------------------------------------------------------- +// Transportaion Layer Enumeration & Information +// --------------------------------------------------------------- + #[repr(u32)] #[derive(Debug, Clone, Copy, FromRepr)] pub enum TransportLayerType { @@ -202,6 +237,10 @@ pub fn transport_layers_list() -> VmbResult> { .collect::>>() } +// --------------------------------------------------------------- +// Interface Enumeration & Information +// --------------------------------------------------------------- + pub struct InterfaceInfo { pub id: String, pub name: String, @@ -258,20 +297,9 @@ pub fn interfaces_list() -> VmbResult> { .collect::>>() } -#[derive(Debug, Clone)] -pub struct CameraInfo { - pub id: String, - pub extended_id: String, - pub camera_name: String, - pub model_name: String, - pub serial_number: String, - pub transport_layer_handle: TransportLayerHandle, - pub interface_handle: InterfaceHandle, - pub local_device_handle: LocalDeviceHandle, - pub stream_handles: StreamHandles, - pub stream_count: u32, - pub access: AccessMode, -} +// --------------------------------------------------------------- +// Camera Enumeration & Information +// --------------------------------------------------------------- #[repr(u32)] #[derive(Debug, Copy, Clone, FromRepr)] @@ -384,6 +412,10 @@ pub fn camera_close(handle: CameraHandle) -> VmbResult<()> { Ok(()) } +// --------------------------------------------------------------- +// Feature Functions +// --------------------------------------------------------------- + pub struct FeatureInfo { pub name: String, pub category: String, @@ -401,6 +433,16 @@ pub struct FeatureInfo { pub has_selected_features: bool, } +pub struct FeatureEnumEntry { + pub name: String, + pub display_name: String, + pub tooltip: String, + pub description: String, + pub int_value: i64, + pub snfc_namespace: String, + pub visibility: FeatureVisibility, +} + #[repr(u32)] #[derive(Debug, Clone, Copy, FromRepr)] pub enum FeatureDataType { @@ -453,35 +495,6 @@ pub fn list_features(handle: &CameraHandle) -> VmbResult> { return Ok(Vec::new()); } - fn convert_feature_info_safe( - camera: mem::MaybeUninit, - ) -> VmbResult { - let feature = unsafe { camera.assume_init() }; - - Ok(FeatureInfo { - name: string_from_raw(feature.name).map_err(|_| VmbError::InternalFault)?, - category: string_from_raw(feature.category).map_err(|_| VmbError::InternalFault)?, - display_name: string_from_raw(feature.displayName) - .map_err(|_| VmbError::InternalFault)?, - tool_tip: string_from_raw(feature.tooltip).map_err(|_| VmbError::InternalFault)?, - description: string_from_raw(feature.description) - .map_err(|_| VmbError::InternalFault)?, - namespace: string_from_raw(feature.sfncNamespace) - .map_err(|_| VmbError::InternalFault)?, - unit: string_from_raw(feature.unit).map_err(|_| VmbError::InternalFault)?, - representation: string_from_raw(feature.representation) - .map_err(|_| VmbError::InternalFault)?, - data_type: FeatureDataType::from_repr(feature.featureDataType) - .ok_or(VmbError::InternalFault)?, - flags: FeatureFlags::from_repr(feature.featureFlags).ok_or(VmbError::InternalFault)?, - polling_time: feature.pollingTime, - visibility: FeatureVisibility::from_repr(feature.visibility) - .ok_or(VmbError::InternalFault)?, - is_streamable: feature.isStreamable & 0x01 == 1, - has_selected_features: feature.hasSelectedFeatures & 0x01 == 1, - }) - } - let mut features_raw: Vec> = vec![mem::MaybeUninit::uninit(); found as usize]; @@ -501,3 +514,708 @@ pub fn list_features(handle: &CameraHandle) -> VmbResult> { .collect::>>() } +fn convert_feature_info_safe(camera: mem::MaybeUninit,) -> VmbResult { + let feature = unsafe { camera.assume_init() }; + + Ok(FeatureInfo { + name: string_from_raw(feature.name).map_err(|_| VmbError::InternalFault)?, + category: string_from_raw(feature.category).map_err(|_| VmbError::InternalFault)?, + display_name: string_from_raw(feature.displayName) + .map_err(|_| VmbError::InternalFault)?, + tool_tip: string_from_raw(feature.tooltip).map_err(|_| VmbError::InternalFault)?, + description: string_from_raw(feature.description) + .map_err(|_| VmbError::InternalFault)?, + namespace: string_from_raw(feature.sfncNamespace) + .map_err(|_| VmbError::InternalFault)?, + unit: string_from_raw(feature.unit).map_err(|_| VmbError::InternalFault)?, + representation: string_from_raw(feature.representation) + .map_err(|_| VmbError::InternalFault)?, + data_type: FeatureDataType::from_repr(feature.featureDataType) + .ok_or(VmbError::InternalFault)?, + flags: FeatureFlags::from_repr(feature.featureFlags).ok_or(VmbError::InternalFault)?, + polling_time: feature.pollingTime, + visibility: FeatureVisibility::from_repr(feature.visibility) + .ok_or(VmbError::InternalFault)?, + is_streamable: feature.isStreamable & 0x01 == 1, + has_selected_features: feature.hasSelectedFeatures & 0x01 == 1, + }) +} + +pub fn feature_info_query(handle: &CameraHandle, name: &str) -> VmbResult { + let feature_name = raw_from_str(name); + + let mut feature_info_raw = mem::MaybeUninit::::uninit(); + let info_size = mem::size_of::() as VmbUint32_t; + + vmb_result(unsafe { + VmbFeatureInfoQuery( + handle.as_raw(), + feature_name, + feature_info_raw.as_mut_ptr(), + info_size, + ) + })?; + + convert_feature_info_safe(feature_info_raw) +} +pub fn list_feature_selected(handle: &CameraHandle, name: &str) -> VmbResult> { + let feature_name = raw_from_str(name); + let mut num_found = 0 as VmbUint32_t; + let feature_info_size = mem::size_of::() as VmbUint32_t; + + vmb_result(unsafe { + VmbFeatureListSelected( + handle.as_raw(), + feature_name, + std::ptr::null_mut(), // empty feature list + 0 as ffi::c_uint, + &mut num_found, + feature_info_size, + ) + })?; + + if num_found == 0 { + return Ok(Vec::new()); + } + + let mut features_raw: Vec> = vec![mem::MaybeUninit::uninit(); num_found as usize]; + + vmb_result(unsafe { + VmbFeatureListSelected( + handle.as_raw(), + feature_name, + features_raw.as_mut_ptr().cast(), + num_found, + &mut num_found, + feature_info_size, + ) + })?; + + features_raw + .iter() + .map(|feature| convert_feature_info_safe(*feature)) + .collect::>>() +} + +pub fn feature_access_query(handle: &CameraHandle, name: &str) -> VmbResult<[i8; 2]> { + let feature_name = raw_from_str(name); + let mut is_readable = false as VmbBool_t; + let mut is_writable = false as VmbBool_t; + + vmb_result(unsafe { + VmbFeatureAccessQuery( + handle.as_raw(), + feature_name, + &mut is_readable, + &mut is_writable, + ) + })?; + + Ok([is_readable, is_writable]) +} + +pub fn feature_int_get(handle: &CameraHandle, name: &str) -> VmbResult { + let feature_name = raw_from_str(name); + let mut value = 0 as VmbInt64_t; + + vmb_result(unsafe { + VmbFeatureIntGet( + handle.as_raw(), + feature_name, + &mut value, + ) + })?; + + Ok(value) +} + +pub fn feature_int_set(handle: &CameraHandle, name: &str, value: i64) -> VmbResult<()> { + let value = value as VmbInt64_t; + let feature_name = raw_from_str(name); + + vmb_result(unsafe { + VmbFeatureIntSet( + handle.as_raw(), + feature_name, + value, + ) + })?; + + Ok(()) +} + +pub fn feature_int_range_query(handle: &CameraHandle, name: &str) -> VmbResult<[i64; 2]> { + let feature_name = raw_from_str(name); + let mut min: i64 = -1 as VmbInt64_t; + let mut max: i64 = -1 as VmbInt64_t; + + vmb_result(unsafe { + VmbFeatureIntRangeQuery( + handle.as_raw(), + feature_name, + &mut min, + &mut max, + ) + })?; + + Ok([min, max]) +} + +pub fn feature_int_increment_query(handle: &CameraHandle, name: &str, value: i64) -> VmbResult { + let feature_name = raw_from_str(name); + let mut value = value as VmbInt64_t; + + vmb_result(unsafe{ + VmbFeatureIntIncrementQuery( + handle.as_raw(), + feature_name, + &mut value, + ) + })?; + + Ok(value) +} + +pub fn feature_int_valid_value_set_query(handle: &CameraHandle, name: &str) -> VmbResult> { + let feature_name = raw_from_str(name); + let mut set_size: u32 = 0; + let buffer_size: u32 = 0; + + // first call to identify size of value set + vmb_result(unsafe { + VmbFeatureIntValidValueSetQuery( + handle.as_raw(), + feature_name, + std::ptr::null_mut(), // pass null pointer to buffer to only return buffer size in buffer_size + buffer_size, + &mut set_size, + ) + })?; + + if set_size == 0 { + return Ok(Vec::new()); + } + + let mut buffer: Vec = vec![0; set_size as usize]; + + // second call to populate buffer + vmb_result(unsafe { + VmbFeatureIntValidValueSetQuery( + handle.as_raw(), + feature_name, + buffer.as_mut_ptr(), + buffer_size, + &mut set_size, + ) + })?; + + Ok(buffer) +} + +pub fn feature_float_get(handle: &CameraHandle, name: &str) -> VmbResult { + let feature_name = raw_from_str(name); + let mut value: f64 = 0.0; + + vmb_result( unsafe { + VmbFeatureFloatGet( + handle.as_raw(), + feature_name, + &mut value, + ) + })?; + + Ok(value) +} + +pub fn feature_float_set(handle: &CameraHandle, name: &str, value: f64) -> VmbResult<()> { + let feature_name = raw_from_str(name); + + vmb_result( unsafe { + VmbFeatureFloatSet( + handle.as_raw(), + feature_name, + value, + ) + })?; + + Ok(()) +} + +pub fn feature_float_range_query(handle: &CameraHandle, name: &str) -> VmbResult<[f64; 2]> { + let feature_name = raw_from_str(name); + let mut min: f64 = -1.0; + let mut max: f64 = -1.0; + + vmb_result(unsafe { + VmbFeatureFloatRangeQuery( + handle.as_raw(), + feature_name, + &mut min, + &mut max, + ) + })?; + + Ok([min, max]) +} + +pub fn feature_float_increment_query(handle: &CameraHandle, name: &str) -> VmbResult { + let feature_name = raw_from_str(name); + let mut hasIncrement = VmbBoolVal_VmbBoolFalse; + let mut value: c_double = 0.0; + + vmb_result(unsafe { + VmbFeatureFloatIncrementQuery( + handle.as_raw(), + feature_name, + &mut hasIncrement, + &mut value, + ) + })?; + + Ok(value) +} + +pub fn feature_enum_get(handle: &CameraHandle, name: &str) -> VmbResult { + let feature_name = raw_from_str(name); + let mut value: *const std::os::raw::c_char = std::ptr::null(); + + vmb_result( unsafe { + VmbFeatureEnumGet( + handle.as_raw(), + feature_name, + &mut value, + ) + })?; + + if value.is_null() { + return Err(VmbError::NoData) + } + + let value = string_from_raw(value).map_err(|_| VmbError::InternalFault)?; + Ok(value) +} + +pub fn feature_enum_set(handle: &CameraHandle, name: &str, value: &str) -> VmbResult<()> { + let feature_name = raw_from_str(name); + let feature_value = raw_from_str(value); + + vmb_result(unsafe { + VmbFeatureEnumSet( + handle.as_raw(), + feature_name, + feature_value, + ) + })?; + + Ok(()) + +} + +pub fn feature_enum_range_query(handle: &CameraHandle, name: &str) -> VmbResult> { + let feature_name = raw_from_str(name); + let mut num_found = 0; + + // first call to identify number of valud enums + vmb_result(unsafe { + VmbFeatureEnumRangeQuery( + handle.as_raw(), + feature_name, + std::ptr::null_mut(), // pass a null pointer to query size + 0, + &mut num_found, + ) + })?; + + if num_found == 0 { + return Ok(Vec::new()); + } + + // allocate space for pointers + let mut raw_ptrs: Vec<*const std::os::raw::c_char> = vec![std::ptr::null(); num_found as usize]; + + // second call writing to raw_ptrs + vmb_result(unsafe { + VmbFeatureEnumRangeQuery( + handle.as_raw(), + feature_name, + raw_ptrs.as_mut_ptr(), + num_found, + &mut num_found, + ) + })?; + + let mut values = Vec::with_capacity(num_found as usize); + for &ptr in &raw_ptrs[..num_found as usize] { + if ptr.is_null() { + continue; + } + + let value = string_from_raw(ptr).map_err(|_| VmbError::InternalFault)?; + values.push(value); + } + + Ok(values) +} + +pub fn feature_enum_is_available(handle: &CameraHandle, name: &str, value: &str) -> VmbResult { + let feature_name = raw_from_str(name); + let feature_value = raw_from_str(value); + let mut is_available = false as VmbBool_t; + + vmb_result(unsafe { + VmbFeatureEnumIsAvailable( + handle.as_raw(), + feature_name, + feature_value, + &mut is_available, + ) + })?; + + Ok(is_available != 0) +} + +pub fn feature_enum_as_int(handle: &CameraHandle, name: &str, value: &str) -> VmbResult { + let feature_name = raw_from_str(name); + let feature_value = raw_from_str(value); + let mut int_value: i64 = -1 as VmbInt64_t; + + vmb_result(unsafe { + VmbFeatureEnumAsInt( + handle.as_raw(), + feature_name, + feature_value, + &mut int_value, + ) + })?; + + Ok(int_value) +} + +pub fn feature_enum_as_string(handle: &CameraHandle, name: &str, int_value: i64) -> VmbResult { + let feature_name = raw_from_str(name); + let mut string_value = std::ptr::null_mut(); + + vmb_result(unsafe { + VmbFeatureEnumAsString( + handle.as_raw(), + feature_name, + int_value as VmbInt64_t, + string_value, + ) + })?; + + let value = string_from_raw(string_value).map_err(|_| VmbError::InternalFault)?; + Ok(value) +} + +pub fn feature_enum_entry_get(handle: &CameraHandle, feature_name: &str, entry_name: &str) -> VmbResult { + let feature_name = raw_from_str(feature_name); + let entry_name = raw_from_str(entry_name); + + let enum_entry_size = mem::size_of::() as VmbUint32_t; + let mut enum_entry: FeatureEnumEntry = unsafe { std::mem::zeroed() }; + + vmb_result(unsafe { + VmbFeatureEnumEntryGet( + handle.as_raw(), + feature_name, + entry_name, + &mut enum_entry as VmbFeatureEnumEntry_t, + enum_entry_size, + ) + })?; + + Ok(enum_entry) +} + +pub fn feature_string_get(handle: &CameraHandle, name: &str) -> VmbResult { + let feature_name = raw_from_str(name); + let mut value_buffer = vec![0u8; 1024]; + + vmb_result(unsafe { + VmbFeatureStringGet( + handle.as_raw(), + feature_name, + value_buffer.as_mut_ptr() as *mut c_char, + value_buffer.len() as u32, + std::ptr::null_mut(), // Change to sizeFilled pointer if desired + ) + })?; + + let value = string_from_raw(value_buffer).map_err(|_| VmbError::InternalFault)?; + Ok(value) +} + +pub fn feature_string_set(handle: &CameraHandle, name: &str, value: &str) -> VmbResult<()> { + let feature_name = raw_from_str(name); + let feature_value = raw_from_str(value); + + vmb_result(unsafe { + VmbFeatureStringSet( + handle.as_raw(), + feature_name, + feature_value, + ) + })?; + + Ok(()) +} + +pub fn feature_string_max_length_query(handle: &CameraHandle, name: &str) -> VmbResult { + let feature_name = raw_from_str(name); + let mut max_length: u32 = 0 as VmbUint32_t; + + vmb_result(unsafe { + VmbFeatureStringMaxlengthQuery( + handle.as_raw(), + feature_name, + &mut max_length, + ) + })?; + + Ok(max_length) +} + +pub fn feature_bool_get(handle: &CameraHandle, name: &str) -> VmbResult { + let feature_name = raw_from_str(name); + let mut value = false as VmbBool_t; + + vmb_result( unsafe { + VmbFeatureBoolGet( + handle.as_raw(), + feature_name, + &mut value, + ) + })?; + + Ok(value != 0) +} + +pub fn feature_bool_set(handle: &CameraHandle, name: &str, value: bool) -> VmbResult<()> { + let feature_name = raw_from_str(name); + let feature_value = match value { + true => VmbBoolVal_VmbBoolTrue, + false => VmbBoolVal_VmbBoolFalse, + }; + + vmb_result( unsafe { + VmbFeatureBoolSet( + handle.as_raw(), + feature_name, + &feature_value, + ) + })?; + + Ok(()) +} + +// --------------------------------------------------------------- +// Command Feature Access +// --------------------------------------------------------------- + +pub fn feature_command_run(handle: &CameraHandle, name: &str) -> VmbResult<()> { + let feature_name = raw_from_str(name); + + vmb_result(unsafe { + VmbFeatureCommandRun( + handle.as_raw(), + feature_name, + ) + })?; + + Ok(()) +} + +pub fn feature_command_is_done(handle: &CameraHandle, name: &str) -> VmbResult { + let feature_name = raw_from_str(name); + let mut is_done: VmbBool_t = VmbBoolVal_VmbBoolFalse; + + vmb_result(unsafe { + VmbFeatureCommandIsDone( + handle.as_raw(), + feature_name, + &mut is_done as *mut VmbBool_t, + ) + })?; + Ok(is_done) +} + + +// --------------------------------------------------------------- +// Image Preparation and Acquisition +// --------------------------------------------------------------- + +pub struct VmbFrame { + // in + pub buffer: *mut c_void, + pub buffer_size: u32, + pub context: [*mut c_void; 4], + + // out + pub recieve_status: VmbFrameStatus_t, // still to be implemented + pub frame_id: u64, + pub timestamp: u64, + pub image_data: *mut u8, + pub receive_flags: VmbFrameFlags_t, + pub pixel_format: VmbPixelFormat_t, + pub width: VmbImageDimension_t, + pub height: VmbImageDimension_t, + pub offset_x: VmbImageDimension_t, + pub offset_y: VmbImageDimension_t, + pub payload_type: VmbPayloadType_t, + pub chunk_data_present: bool, +} + + +pub fn payload_size_get(handle: &CameraHandle) -> VmbResult { + let mut payload_size: u32 = 0 as VmbUint32_t; + + vmb_result(unsafe { + VmbPayloadSizeGet( + handle.as_raw(), + &mut payload_size, + ) + })?; + + Ok(payload_size) +} + +pub fn frame_announce(handle: &CameraHandle, frame: VmbFrame, size_of_frame:u16) -> VmbResult<()> { + vmb_result(unsafe { + VmbFrameAnnounce( + handle.as_raw(), + frame as VmbFrame, + &mut size_of_frame, + ) + })?; + + Ok(()) +} + +pub fn frame_revoke(handle: &CameraHandle, frame: VmbFrame) -> VmbResult<()> { + vmb_result(unsafe { + VmbFrameRevoke( + handle.as_raw(), + frame as VmbFrame, + ) + })?; + + Ok(()) +} + +pub fn frame_revoke_all(handle: &CameraHandle) -> VmbResult<()> { + vmb_result(unsafe {VmbFrameRevokeAll(handle)})?; + + Ok(()) +} + +pub fn capture_start(handle: &CameraHandle) -> VmbResult<()> { + vmb_result(unsafe { + VmbCaptureStart( + handle.as_raw() + ) + })?; + + Ok(()) +} + +pub fn capture_end(handle: &CameraHandle) -> VmbResult<()> { + vmb_result(unsafe { + VmbCaptureEnd( + handle.as_raw() + ) + })?; + + Ok(()) +} + +pub fn capture_frame_queue(handle: &CameraHandle, frame: &VmbFrame, callback: VmbFrameCallback) -> VmbResult<()> { + vmb_result(unsafe { + VmbCaptureFrameQueue( + handle.as_raw(), + frame as *const VmbFrame, + callback, + ) + })?; + + Ok(()) +} + +pub fn capture_frame_wait(handle: &CameraHandle, frame: &VmbFrame, timeout: u32) -> VmbResult<()>{ + vmb_result(unsafe { + VmbCaptureFrameWait( + handle.as_raw(), + frame as *const VmbFrame, + timeout as VmbUint32_t, + ) + })?; + + Ok(()) +} + +pub fn capture_queue_flush(handle: &CameraHandle) -> VmbResult<()> { + vmb_result(unsafe { + VmbCaptureQueueFlush(handle.as_raw()) + + })?; + + Ok(()) +} + +// --------------------------------------------------------------- +// Direct Access +// will be implemented if a use case is found +// --------------------------------------------------------------- + +// pub fn memory_read() +// pub fn memory_write() + +// pub fn registers_read() +// pub fn registers_write() + +// pub fn chunk_data_access() +// pub fn chunk_access_callback() + +// --------------------------------------------------------------- +// Load & Save Settings +// --------------------------------------------------------------- + +pub struct PersistSettings { + pub persist_type: u32, + pub module_persist_flags: u32, + pub max_iterations: u32, +} + + +pub fn camera_settings_save(handle: &CameraHandle, filepath: &str, settings: PersistSettings) -> VmbResult<()> { + // TODO: determine if this is how filepath is to be calculated + // determine how to calculate size_of_settings in bytes for C instead of rust + let filepath = raw_from_str(filepath); + let size_of_settings: u32 = 0; + + vmb_result(unsafe { + VmbSettingsSave( + handle.as_raw(), + filepath, + settings, + size_of_settings, + ) + })?; + + Ok(()) +} + +pub fn camera_settings_load(handle: &CameraHandle, filepath: &str, settings: PersistSettings) -> VmbResult<()> { + let filepath = raw_from_str(filepath); + let size_of_settings: u32 = 0; + + vmb_result(unsafe { + VmbSettingsLoad( + handle.as_raw(), + filepath, + settings, + size_of_settings + ) + }) +} + diff --git a/src/utils.rs b/src/utils.rs index 705d564..0c3a0d7 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,4 +1,4 @@ -use std::{ffi, str::Utf8Error}; +use std::{ffi, ffi::CString, ffi::NulError, str::Utf8Error}; use crate::{error::VmbError, ffi::VmbError_t}; @@ -6,6 +6,8 @@ pub fn string_from_raw(raw: *const ffi::c_char) -> Result { unsafe { Ok(ffi::CStr::from_ptr(raw).to_str()?.to_string()) } } +pub fn raw_from_str(string: &str) -> *const ffi::c_char { string.as_ptr().cast() } + pub fn vmb_result(err: VmbError_t) -> Result<(), VmbError>{ match VmbError::from_repr(err) { Some(e) => Err(e), diff --git a/wrapper.h b/wrapper.h index f03b98a..cdf448b 100644 --- a/wrapper.h +++ b/wrapper.h @@ -1 +1 @@ -#include "/opt/VimbaX_2025-2/api/include/VmbC/VmbC.h" +#include "/opt/VimbaX_2025-3/api/include/VmbC/VmbC.h"