1个不稳定版本
使用旧的Rust 2015
0.0.0 | 2024年5月18日 |
---|
#4 在 #objc2
1KB
Rust中的Objective-C
你可能感兴趣的crate是
objc2
,它提供Rust和Objective-C之间的双向互操作性,包括在Rust中定义Objective-C类。objc2-*
crate,它提供自动生成的接口,用于苹果的Objective-C框架(如AppKit
、Foundation
、Metal
、WebKit等,只要你想,我们就会实现)。
block2
,它提供了对苹果C块绑定的支持,这是Rust闭包的C等价物。
联系我们
随时可以在GitHub上提出问题。
如果你更喜欢同步且不太“正式”的讨论,我们有一个Matrix工作区,在“用户”房间中随时可以提问。
目标
在这样一个开源项目(性能、易用性、可理解性、可移植性等)中有很多冲突的优先级,但以下两点可以被视为本项目的指导原则。
1. 完全正确性
这些crate的不可谈判的目标是做到完全“正确”,这意味着它绝对不能让安全的Rust引起未定义的行为!
截至2023年1月,我(@madsmtm
)还没有发现任何一个Rust crate或项目能够正确地调用Objective-C。我发现的问题包括
- 错误的方法调用ABI。
- 错误的内存管理(在最好的情况下,它们只是泄漏很多)。
- 错误的
&mut
使用。 - 错误的主线程安全性。
我并不是要贬低这些项目,这是完全可以理解的!Objective-C 和 Rust 的语义有很大的不同,因此解决这些问题需要警惕和专注,例如系统剪贴板库就根本不具备这种专注!相反,我这样说是为了提供保证:Rust 的无畏并发可以重新获得!该项目针对该问题的方法 有效,漏掉、段错误、竞争条件等问题可以完全消除!
不用说,没有什么是完美的,所以如果你认为你发现了一个安全漏洞,请毫不犹豫地在问题跟踪器上报告。已知的漏洞(无论理论如何)都记录在I-unsound
标签中。
2. Rust 风格
如果我们只是将每个 API 都标记为 unsafe
,那么实现安全性就很容易了(这个做法的先例 objc
基本上是安全的)。然而,这样做只是将负担转移到了你,用户身上,我们并没有变得更好!
因此,我们将尽可能地做到既安全又符合 Rust 风格;用引用而不是指针来表示对象及其可变性,用 Option
而不是 null
,自动进行内存管理而不是手动管理,等等(请参阅关于“分层安全”的这些说明)。这些抽象理想情况下应该是零成本的,但当然,这是在易用性和成本之间的一种平衡。
在 objc2
和 block2
中的一些 API 仍然需要保持 unsafe
,因此这些包含详尽的 # Safety
部分,以便让你确切知道你需要维护哪些安全保证。框架库在这方面有些困难,因为它们大多是自动生成的,这意味着几乎没有什么可以默认是安全的!然而,我们仍然可以通过手动标记审核过的功能为安全来尝试减轻这个问题(我们需要你的帮助)。
最低支持的 Rust 版本 (MSRV)
目前最低支持的 Rust 版本是 1.60
;这并不是由政策定义的,所以它可能在任何补丁版本中随时改变。
在#203 中帮助我们定义一个政策。
从 objc
和家族迁移
如果你的项目规模相对较小,最简单的方法可能是直接跳到使用框架库来替换所有内容(当你这样做的时候,别忘了在过程中将你使用的 unsafe
方法标记为安全)。
如果你的项目规模较大,你可以考虑逐步升级,在每个步骤中遵循更改日志。对于最常见的案例,更改日志将包括有关如何升级的有用示例。
例如,你可以首先在你的 Cargo.toml
中用 objc2
替换 objc
。
[dependencies]
objc = { package = "objc2", version = "0.2.7" }
然后,你可以升级到下一个版本,在这个例子中是 v0.3.0-alpha.0
,并按照更改日志对你的代码进行必要的修改。以此类推,随着每个后续版本的发布。
许可协议
本项目采用MIT许可证,详见LICENSE.txt
。
目前正在努力使其同时获得Apache许可证(版本2.0)的许可,详见此处。
致谢/先前艺术
此存储库是以下项目的合并,有关分叉的理由请参见此处
objc
- 重命名为
objc2
。
- 重命名为
objc-encode
- 重命名为
objc2-encode
。
- 重命名为
objc_exception
- 移动到
objc2::exception
。
- 移动到
objc_id
- 移动到
objc2::rc
。
- 移动到
objc-foundation
- 重命名为
objc2-foundation
。
- 重命名为
block
- 重命名为
block2
。
- 重命名为
这些几乎完全由@SSheldon创建,因此对他们在这方面的出色工作表示衷心的感谢!
本项目还受到以下项目的启发
apple-sys
cacao
- 的
core-foundation-rs
项目 fruity
metal
objrs
objr
和家族rust-macios
uikit-sys
和bindgen的Objective-C工作@simlay。cidre
最后,这绝对不是第一个尝试与Objective-C交互的项目;其他语言也尝试过(成功率各不相同)
- Swift:从一开始就是为了Objective-C交互而构建的,并且是
objc2
希望与之具有功能相同性的(尽管可能永远达不到)。真正设计精美的语言! - C#:Xamarin,Xamarin.Mac,是“应该”工作的好灵感来源。
- Python:PyObjC(以前?)官方Apple项目,与“BridgeSupport”一起工作,现在他们还通过调用Clang生成元数据。其他包括
objp
和rubicon.objc。 - Ruby:MacRuby,RubyCocoa
- Dart:
ffigen
- Kotlin:有些内置支持
- Nim:有些内置支持,
darwin
,objc
- D:有些内置支持,
derelict
- Java:Java-Objective-C-Bridge,Multi-OS Engine: Nat/J(还有一个生成器),Apple还有一个非常古老的项目。
- Node.js:NodObjC,
objc
- Zig:zig-objcrt
- D:有些内置支持,
derelict
- V:实际上并不存在,他们只是编写和编译Objective-C代码,并使用手动C绑定。
- Go:MacDriver