1个不稳定版本
使用旧的Rust 2015
0.0.0 | 2024年5月18日 |
---|
6 in #objc2
1KB
Rust中的Objective-C
你可能感兴趣的crate是
objc2
,它提供Rust和Objective-C之间的双向互操作,包括在Rust中定义Objective-C类的支持。objc2*
crates,它提供自动生成的接口,用于Apple的Objective-C框架(例如AppKit
、Foundation
、Metal
、WebKit
等,我们旨在提供所有这些)。block2
,它提供Apple的C blocks的绑定,这是Rust闭包的C等价物。
联系我们
随时在GitHub上打开一个问题。
如果您更喜欢更同步和不太“正式”的讨论,我们有一个Matrix工作空间,您可以在“用户”房间中自由提问。
目标
在这样一个开源项目中,有很多相互冲突的优先事项(性能、易用性、可理解性、可移植性等),但以下两个可以被视为该项目中所有其他内容的指导原则。
1. 完全正确性
这些crate的不可谈判的目标是做到完全“正确”,这意味着它绝对不能让安全的Rust造成未定义的行为!
截至2023年1月,我(@madsmtm
)尚未找到任何调用Objective-C的Rust crate或项目是正确的。我发现的问题包括
- 错误的方法调用ABI。
- 错误的内存管理(在最好的情况下,它们只是大量泄漏)。
- 不正确的使用
&mut
。 - 不正确的主线程安全性。
我并不是要贬低这些项目,这是完全可以理解的!Objective-C 和 Rust 的语义差异很大,因此解决这些问题需要警觉性和专注力,例如系统剪贴板库就缺乏这种能力!相反,我这样说是为了提供保证:Rust 的无畏并发能力可以重新获得!本项目对问题的处理方法是有效的,泄漏、段错误、竞态条件等问题也可以完全消除!
不用说,没有什么是完美的,所以如果您认为您发现了某个安全性漏洞,请毫不犹豫地在问题跟踪器上报告。已知的漏洞(无论理论上的还是实际上的)都记录在I-unsound
标签下。
2. Rust 的惯用法
如果我们只是将每个 API 标记为 unsafe
并就此了事,那么保证安全性会变得很容易(这个过程的先导 objc
基本上是安全的)。然而,这只会将负担推给用户,我们并没有变得更好!
因此,我们将尽量做到既安全又符合惯用法;使用引用而不是指针来表示对象及其可变性,使用 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
和@simlay
的 Objective-C work onbindgen
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(同时还有一个生成器),苹果也拥有一个非常老的项目。
- Node.js: NodObjC,
objc
- Zig: zig-objcrt
- D:有些内置支持,
derelict
- V: 实际上并不存在,他们只是编写和编译 Objective-C 代码,并使用手动 C 绑定。
- Go: MacDriver