diff --git a/cpp/src/usbmuxd.cpp b/cpp/src/usbmuxd.cpp index 5c4fb04..aff8857 100644 --- a/cpp/src/usbmuxd.cpp +++ b/cpp/src/usbmuxd.cpp @@ -117,6 +117,7 @@ Result, FfiError> UsbmuxdConnection::get_devices() co for (int i = 0; i < count; ++i) { out.emplace_back(UsbmuxdDevice::adopt(list[i])); } + idevice_outer_slice_free(list, count); return Ok(std::move(out)); } diff --git a/ffi/src/lib.rs b/ffi/src/lib.rs index ff60a17..4e5f67d 100644 --- a/ffi/src/lib.rs +++ b/ffi/src/lib.rs @@ -50,7 +50,7 @@ use idevice::{Idevice, IdeviceSocket, ReadWrite}; use once_cell::sync::Lazy; use plist_ffi::PlistWrapper; use std::{ - ffi::{CStr, CString, c_char}, + ffi::{CStr, CString, c_char, c_void}, ptr::null_mut, }; use tokio::runtime::{self, Runtime}; @@ -432,3 +432,18 @@ pub unsafe extern "C" fn idevice_plist_array_free(plists: *mut plist_t, len: usi } } } + +/// Frees a slice of pointers allocated by this library that had an underlying +/// vec creation. +/// +/// The following functions use an underlying vec and are safe to use: +/// - idevice_usbmuxd_get_devices +/// +/// # Safety +/// Pass a valid pointer passed by the Vec creating functions +#[unsafe(no_mangle)] +pub unsafe extern "C" fn idevice_outer_slice_free(slice: *mut c_void, len: usize) { + if !slice.is_null() { + let _ = unsafe { Vec::from_raw_parts(slice, len, len) }; + } +}