Как передать аргумент в Swift функции C, которая принимает UnsafePointer? - PullRequest
0 голосов
/ 27 февраля 2020

Я импортировал C функцию с именем geoToH3, которая возвращает H3Index (что является просто UInt64).

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

Функция принимает Int32 и GeoCoord объект, который является просто объектом с парой Double.

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

Как передать аргумент geoCoord этой функции, поскольку она принимает UnsafePointer?

Ответы [ 2 ]

1 голос
/ 27 февраля 2020

Просто позвоните учащемуся, который содержит имя UnsafePointer.

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

Попробуйте этот пример:

Мой C. 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. Создайте файл My C. c и введите код.

enter image description here

Нажмите на свой проект. Нажмите на вкладку Build Setting. Выберите все вкладки Поиск с Objective- c Заголовок моста Дважды щелкните здесь. После этого щелкните левой кнопкой мыши на файле My C. c и перетащите его внутрь всплывающего слоя.

enter image description here

Вы можете определить свою функцию в Practice-Bridging-Header.h

void changeInput (int * output);

enter image description here

Введите код внутри вашего ViewController.

Код:

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 голос
/ 27 февраля 2020

withUnsafePointer(to:) должно использоваться здесь:

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

или короче (с использованием сокращенного синтаксиса параметра и неявного возврата):

let h3Index = withUnsafePointer(to: geoCoord) { geoToH3($0, 5) }
  • withUnsafePointer(to:) вызывает замыкание с указателем на значение geoCoord.
  • Функция C вызывается с указателем в качестве первого аргумента.
  • Возвращаемое значение из C function является возвращаемым значением withUnsafePointer(to:) и присваивается h3Index.

Важно, что указатель действителен только во время выполнения withUnsafePointer(to:) и не должен храниться или возвращаться для позже используйте.

Например, следующее поведение будет неопределенным:

let pointer = withUnsafePointer(to: geoCoord) { return $0 }
let h3Index = geoToH3(pointer, 5)
...