当前位置: 首页 > 面试题库 >

MACH_TASK_BASIC_INFO的Swift指针问题

卫高明
2023-03-14
问题内容

我正在尝试将答案转换为Swift并失败。似乎我正在传递一个UnsafeMutablePointer<mach_msg_type_number_t>应该何时传递一个,inout mach_msg_type_number_t而我似乎无法解决我的问题。据我了解的Swift指针文档(不多),这些应该可以互换。

下面的更多信息。

这是目标C:

struct task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);

这是我所掌握的Swift语言(很多行可以简化类型检查)

let name: task_name_t = mach_task_self_
let flavor: task_flavor_t = task_flavor_t(MACH_TASK_BASIC_INFO)
var info: mach_task_basic_info
var size: mach_msg_type_number_t = UnsignedFixed(sizeof(mach_task_basic_info_t))
let kerr = task_info(name, flavor, info as task_info_t, &size)

task_info签名是:

func task_info(target_task: task_name_t, flavor: task_flavor_t, task_info_out: task_info_t, task_info_outCnt: UnsafeMutablePointer<mach_msg_type_number_t>) -> kern_return_t

最后一行的错误是:

Cannot convert the expression's type '(@!lvalue task_name_t, task_flavor_t, task_info_t, inout mach_msg_type_number_t)' to type 'kern_return_t'

问题答案:

与C函数进行交互时,您不能依靠编译器的错误消息-逐个参数地将其分解,然后单击命令直至知道要使用的内容。首先,您遇到的类型是:

  • task_name_tUInt32
  • task_flavor_tUInt32
  • task_info_tUnsafeMutablePointer<Int32>
  • UnsafeMutablePointer<mach_msg_type_number_t>UnsafeMutablePointer<UInt32>
  • kern_return_t -- Int32

这里有一个棘手的Swift位以及代码中的一个错误,阻碍了您的发展。首先,task_info_out参数必须为UnsafeMutablePointer<UInt32>,但实际上需要指向的实例mach_task_basic_info。我们可以通过在调用时创建一个UnsafeMutablePointer<mach_task_basic_info>并将其包装在
另一个 包装中来解决此问题UnsafeMutablePointer-编译器将使用类型推断来知道我们希望将包装指针子类型化为UInt32

其次,您在
应调用时正在调用 sizeof(mach_task_basic_info_t)(指向的指针 mach_task_basic_infosizeinfo(mach_task_basic_info),因此字节数最终太少而无法容纳数据结构。

在进一步的研究中,这变得更加复杂。原始代码不正确,size应将其初始化为constant
MACH_TASK_BASIC_INFO_COUNT。不幸的是,这是一个宏,而不是简单的常量:

#define MACH_TASK_BASIC_INFO_COUNT (sizeof(mach_task_basic_info_data_t) / sizeof(natural_t))

Swift不会导入这些,因此我们需要自己重新定义。这是所有这些的工作代码:

// constant
let MACH_TASK_BASIC_INFO_COUNT = (sizeof(mach_task_basic_info_data_t) / sizeof(natural_t))

// prepare parameters
let name   = mach_task_self_
let flavor = task_flavor_t(MACH_TASK_BASIC_INFO)
var size   = mach_msg_type_number_t(MACH_TASK_BASIC_INFO_COUNT)

// allocate pointer to mach_task_basic_info
var infoPointer = UnsafeMutablePointer<mach_task_basic_info>.alloc(1)

// call task_info - note extra UnsafeMutablePointer(...) call
let kerr = task_info(name, flavor, UnsafeMutablePointer(infoPointer), &size)

// get mach_task_basic_info struct out of pointer
let info = infoPointer.move()

// deallocate pointer
infoPointer.dealloc(1)

// check return value for success / failure
if kerr == KERN_SUCCESS {
    println("Memory in use (in bytes): \(info.resident_size)")
} else {
    let errorString = String(CString: mach_error_string(kerr), encoding: NSASCIIStringEncoding)
    println(errorString ?? "Error: couldn't parse error string")
}


 类似资料:
  • 问题内容: 我的应用程序使用某种复杂的不可变数据结构,该结构以二进制文件编码。我需要在字节级别访问它,避免任何复制。通常,我将使用C或C ++指针算术和类型转换来访问和解释原始字节值。我想对Swift做同样的事情。 我发现以下作品: 但是,我不确定它的效率如何。每次我调用对象时都要做和分配对象,或者它们只是用于处理指针的语法糖吗? 在Swift中有更好的方法吗? 编辑: 我创建了一个小的Objec

  • 问题内容: 我正在将一个应用程序从Objective-C移植到Swift,我需要使用以下方法: 原来的逻辑看起来像这样(几个网站似乎对此表示同意): 借助免费的桥接功能,效果很好。但是,“快速空间”中不存在ARC,并且类型系统已更改。 如何将流转换为 然后在调用之后将它们转换回子类? 问题答案: 我可以使用它,这是我的代码:确保在某处保留连接类的引用:-)

  • 指针可以指向一份普通类型的数据,例如 int、double、char 等,也可以指向一份指针类型的数据,例如 int *、double *、char * 等。 如果一个指针指向的是另外一个指针,我们就称它为 二级指针,或者 指向指针的指针。 假设有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示: 将这种关系转换为C语言代码: 指针变

  • 指针不是存放首地址吗,怎么不一样呢

  • 6. 指向指针的指针与指针数组 指针可以指向基本类型,也可以指向复合类型,因此也可以指向另外一个指针变量,称为指向指针的指针。 int i; int *pi = &i; int **ppi = &pi; 这样定义之后,表达式*ppi取pi的值,表达式**ppi取i的值。请读者自己画图理解i、pi、ppi这三个变量之间的关系。 很自然地,也可以定义指向“指向指针的指针”的指针,但是很少用到: int

  • 011. Container With Most Water 问题 Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is