Skip to content

czf0613/swift_lib

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

果系专属?拿来吧你

如何在Apple的亲儿子语言(OC,Swift)之外的地方,使用macOS/iOS的一些原生功能? macOS系统中有大量离线、免费且好用的框架,比如说OCR、VideoToolbox、AudioToolBox等等,但是这些东西基本上只有OC或者Swift接口,但是我的项目主要语言并不是Swift或OC的时候,应该怎么办?

原理:FFI

所有的编程语言基本上都有C ABI(我没打错字,就是ABI)打交道的方式,例如Rust FFI,Java JNI,python ctypes等等。也就是说,只要你能生成一个C语言规范的接口,别的语言就有办法调用你。

(题外话)为什么C++不行?

C++有name mangling机制,是为了函数重载,但是C++并未对name mangling有明确要求,导致不同的编译器实现很可能不一样,也就破坏了兼容性。

OC也是C

OC语言实际上是C语言的一个扩展,只需稍加改造,它是可以生成C兼容的函数接口的(header中不要import Apple专有库就足矣)。然后Apple也很贴心为我们提供了OC到Swift的桥接机制。所以,我们整个调用的逻辑就是: C API --> OC --桥接--> Swift

(题外话)桥接有没有性能开销

当然有,只不过这个东西已经被果子优化得很好了,除非你在做非常高性能的计算,否则这一点性能差距完全看不出来。当然,如果你真的很追求性能的话,你早也不应该在Swift中使用高度封装的数据类型(比如NSData, NSString, NSArray),你就应该直接操作裸指针。

为啥不直接Swift生成C API,越过OC桥接呢?

原理上来说这个确实是最佳方案,可惜截止发稿日期,我没有见到有任何官方的说明或者稳定可用的方案告诉我可以这样搞。也许以后这个功能会有,那就不需要中转OC了。

macOS动态库加载规则

macOS加载动态库用到的是一个install name机制。默认的install name可能会让你安装去一个需要高权限的地址,这个是不合适的。 大部份的软件我们都可能需要进行打包才能分发,所以使用相对路径的加载机制就会比较合适。所以,相对于可执行文件的路径就非常合适,也就是@executable_path。 修改之后,编译后的程序就会自动去指定地方找动态链接库了。

About

How to make a macOS dylib with Swift or OC

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published