来自swift的C数组内存释放

时间:2014-10-25 13:08:56

标签: ios macos swift interop xcode6

var cpuInfo: processor_info_array_t = nil
var numCpuInfo: mach_msg_type_number_t = 0
var coresTotalUsage: Float = 0.0
var numCPUsU: natural_t = 0
let err = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numCPUsU, &cpuInfo, &numCpuInfo);
assert(err == KERN_SUCCESS, "Failed call to host_processor_info")

嗨,我正在调用上面的C API host_processor_info来从swift获取进程加载信息,没问题。 cpuInfo是一个inout参数(指针),返回时将指向包含该API分配的CPU信息的结构。 调用者负责释放内存;我可以从客观的C轻松地做到这一点,但是没有快速的运气。我知道我可以将这个调用包装成一个客观的C扩展,但我试图学习swift,并且如果可能的话,希望避免使用obj-c解决方案。

在obj-c中我将解除分配:

size_t cpuInfoSize = sizeof(integer_t) * numCpuInfo;
vm_deallocate(mach_task_self(), (vm_address_t) cpuInfo, cpuInfoSize)
swift中的cpuInfo是一个不能转换为vm_address_t的UnsafeMutablePointer。

感谢任何帮助,谢谢。

2 个答案:

答案 0 :(得分:5)

processor_info_array_t是指针类型,vm_address_t是整数类型 (最终是UInt的别名)。 (从<i386/vm_types.h>中的评论来看 这可能是出于历史原因。) 在Swift中将指针转换为整数(大小相同)的唯一方法是unsafeBitCast

mach_init.h定义

extern mach_port_t      mach_task_self_;
#define mach_task_self() mach_task_self_

只有外部变量在Swift中可见,而不是宏。

这给出了:

let cpuInfoSize = vm_size_t(sizeof(integer_t)) * vm_size_t(numCpuInfo)
vm_deallocate(mach_task_self_, unsafeBitCast(cpuInfo, vm_address_t.self), cpuInfoSize)

答案 1 :(得分:3)

在Swift 4中,等效代码似乎是:

let cpuInfoSize = vm_size_t(MemoryLayout<integer_t>.stride * Int(numCpuInfo))
vm_deallocate(mach_task_self_, vm_address_t(bitPattern: cpuInfo), cpuInfoSize)

特别是,初始化程序UInt(bitPattern:)现在显然优于unsafeBitCast()以使用指针的位模式初始化无符号整数(我猜这种用法不再被视为“不安全”)。它正确处理nil指针,在这种情况下返回0。