How can I pass complex swift datatypes to C datatypes when calling native functions in iOS/MacOS?
我设法获得了一个包含在框架中的基本 dylib,它允许我传入 Int 并返回和 Int 工作,但我将如何传递和返回更复杂的数据类型,如指针、字节数组或实际数据结构快速到 C dylib?
是否有任何教程或资源可以将 swift 数据类型映射/传递/转换为 C 数据类型,反之亦然,就像在 JNI for java 中一样?
在 Swift 端解释 C 结构并从 c-dylib 动态提取函数的示例如下所示:
.c 文件
1
2 3 4 5 6 7 8 9 10 11 12 13 |
.h 文件
1
2 3 4 5 |
typedef struct {
char *first_name; char *last_name; int age; } Person; |
斯威夫特
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
typealias getPersonFunc = @convention(c) () -> UnsafeMutablePointer<Person> typealias freePersonFunc = @convention(c) (UnsafeMutablePointer<Person>) -> Void … let handle = dlopen("libsimple.dylib", RTLD_LOCAL|RTLD_NOW) print(firstName) let free_person_sym = dlsym(handle,"free_person") dlclose(handle) |
测试
此示例在调试控制台上的输出如下所示:
1
2 3 |
Branford
Marsalis 60 |
从 Swift 到 C
假设在 .c:
1
2 3 4 5 6 7 |
void print_person(Person *person) {
printf("%s %s is %d years old/ ", person->first_name, person->last_name, person->age); } |
然后在 Swift 方面可以这样写:
1
2 3 4 5 6 7 8 9 10 |
typealias printPersonFunc = @convention(c) (UnsafeMutablePointer<Person>) -> Void
… let newPerson = UnsafeMutablePointer<Person>.allocate(capacity: 1) newPerson.pointee.first_name = UnsafeMutablePointer<Int8>(mutating: ("Norah" as NSString).utf8String) newPerson.pointee.last_name = UnsafeMutablePointer<Int8>(mutating: ("Jones" as NSString).utf8String) newPerson.pointee.age = 41 let print_person_sym = dlsym(handle,"print_person") let printPerson = unsafeBitCast(print_person_sym, to: printPersonFunc.self) printPerson(newPerson) newPerson.deallocate() |
这将在控制台上给出以下输出:
1
|
Norah Jones is 41 years old
|
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/268689.html