Rust中注册回调时如何保留Allocation所有权?Vulkan开发问题
解决DeletionQueue中闭包捕获Allocation所有权的问题
核心思路是用Option包裹Allocation实例,延迟将所有权转移给闭包,直到执行释放操作时才通过take()取出所有权,这样后续代码仍能通过Option的引用访问分配的内存。
步骤1:用Option存储Allocation
将分配得到的Allocation存入Option,保留后续访问的能力:
// 分配内存并将结果存入Option let mut draw_image_allocation = Some( allocator.allocate(&gpu_allocator::vulkan::AllocationCreateDesc { name: "Draw Image Allocation", requirements: image_memory_requirements, // 你的图像内存需求 location: gpu_allocator::MemoryLocation::GpuOnly, linear: true, }).unwrap() );
步骤2:注册带延迟所有权转移的删除器
修改闭包逻辑,通过take()从Option中取出所有权再执行释放,避免提前夺走分配实例的使用权:
deletion_queue.push_deletor(Box::new(move || { // 取出所有权后原Option变为None,防止后续误用已释放的内存 if let Some(allocation) = draw_image_allocation.take() { unsafe { allocator.free(allocation).unwrap(); } } }));
后续使用Allocation的方式
需要访问分配的内存时,通过as_ref()获取引用即可:
// 示例:绑定图像内存 let allocation_ref = draw_image_allocation.as_ref().unwrap(); unsafe { vk.bind_image_memory(device, image, allocation_ref.memory(), allocation_ref.offset()).unwrap(); }
额外注意:Allocator的生命周期问题
如果allocator的生命周期短于DeletionQueue,可以将其包裹在Arc中,让闭包捕获Arc的克隆来延长生命周期:
use std::sync::Arc; let allocator = Arc::new(allocator); let mut draw_image_allocation = Some( allocator.allocate(/* 分配参数 */).unwrap() ); deletion_queue.push_deletor(Box::new(move || { let allocator_clone = allocator.clone(); if let Some(allocation) = draw_image_allocation.take() { unsafe { allocator_clone.free(allocation).unwrap(); } } }));
内容的提问来源于stack exchange,提问作者Francisco José Letterio
相关产品推荐
相关产品推荐

