如何将 Swift 中的参数传递给采用 UnsafePointer 的 C 函数?

How to pass argument in Swift to C function that takes an UnsafePointer?

我导入了一个名为 geoToH3 的 C 函数,它 returns 一个 H3Index(这只是一个 UInt64)。

let h3Index = geoToH3(g: UnsafePointer<GeoCoord>!, r: Int32)

该函数接受一个Int32和一个GeoCoord对象,它只是一个带有一对Double.

的对象
let geoCoord = GeoCoord(lat: 45.0, lon: -90.0)

如何将 geoCoord 参数传递给此函数,因为它需要一个 UnsafePointer

这里必须使用

withUnsafePointer(to:)

let h3Index = withUnsafePointer(to: geoCoord) {
     (pointer: UnsafePointer<GeoCoord>) -> H3Index in
     return geoToH3([=10=], 5)
}

或更短(使用 shorthand 参数语法和隐式 return):

let h3Index = withUnsafePointer(to: geoCoord) { geoToH3([=11=], 5) }
  • withUnsafePointer(to:) 使用指向 geoCoord 值。
  • 使用该指针作为第一个参数调用 C 函数。
  • C 函数的 return 值是 withUnsafePointer(to:) 的 return 值并分配给 h3Index

重要的是,指针仅在 withUnsafePointer(to:) 执行期间有效,不得存储或 returned 供以后使用。

例如,以下是未定义的行为:

let pointer = withUnsafePointer(to: geoCoord) { return [=12=] }
let h3Index = geoToH3(pointer, 5)

只需调用包含 UnsafePointer 名称的学生参考即可。

let stu = student(id: 1, name: input?.cString(using: .utf8), percentage: 10.0)
passByStudent(stu)

试试这个例子:

MyC.c

#include <stdio.h>

void changeInput(int *output) {
    *output = 5;
}

typedef struct student Student ;

void passByStudent(Student stu);

struct student {
    int id;
    const char *name;
    float percentage;
};

void passByStudent(Student stu) {
    stu.id = 5;
}

ViewController.swift

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        var output: CInt = 0
        changeInput(&output)
        print("output: \(output)")


        let input: String? = "strudent name"
        let stu = student(id: 1, name: input?.cString(using: .utf8), percentage: 10.0)
        passByStudent(stu)
    }
}

逐步执行此示例:

  1. 创建一个 Swift 项目

  2. 创建MyC.c文件并编写代码。

  1. 单击您的项目。
  2. 单击构建设置选项卡。
  3. Select 所有选项卡
  4. 使用 Objective-c 桥接头搜索
  5. 双击此处。
  6. 然后左键单击 MyC.c 文件,拖放到弹出层中。

  1. 你可以在Practice-Bridging-Header.h

    里面定义你的函数

    void changeInput(int *output);

  1. 在您的 ViewController.
  2. 中编写代码

代码:

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        var output: CInt = 0
        changeInput(&output)
        print("output: \(output)")


        let input: String? = "strudent name"
        let stu = student(id: 1, name: input?.cString(using: .utf8), percentage: 10.0)
        passByStudent(stu)
    }
}