如何将 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
?
这里必须使用
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)
}
}
逐步执行此示例:
创建一个 Swift 项目
创建MyC.c文件并编写代码。
- 单击您的项目。
- 单击构建设置选项卡。
- Select 所有选项卡
- 使用 Objective-c 桥接头搜索
- 双击此处。
- 然后左键单击 MyC.c 文件,拖放到弹出层中。
你可以在Practice-Bridging-Header.h
里面定义你的函数
void changeInput(int *output);
- 在您的 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)
}
}
我导入了一个名为 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
?
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)
}
}
逐步执行此示例:
创建一个 Swift 项目
创建MyC.c文件并编写代码。
- 单击您的项目。
- 单击构建设置选项卡。
- Select 所有选项卡
- 使用 Objective-c 桥接头搜索
- 双击此处。
- 然后左键单击 MyC.c 文件,拖放到弹出层中。
你可以在Practice-Bridging-Header.h
里面定义你的函数void changeInput(int *output);
- 在您的 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)
}
}