Rust系统级核心功能库CoreFoundation-sys的使用,CoreFoundation-sys提供底层跨平台系统API绑定与基础框架交互
CoreFoundation Rust Bindings
CoreFoundation-sys
包提供了在 macOS 上对 CoreFoundation
C 库的声明和链接。遵循 *-sys
包的约定,CoreFoundation-sys
包不定义对原生库的高级抽象。
状态
CoreFoundation-sys
crate 还在开发中。它目前导出了 CoreFoundation 中最基本的类型(数组、字典、字符串等)和函数,并且只在 macOS 的 x86_64 架构上进行了测试。
使用方法
在 Cargo.toml
中添加 CoreFoundation-sys
作为依赖:
[dependencies]
CoreFoundation-sys = "0.1.4"
导入 CoreFoundation_sys
crate 并使用 Apple 提供的原生 CoreFoundation
库中定义的函数:
extern crate CoreFoundation_sys as cf;
完整示例代码
下面是一个使用 CoreFoundation-sys 创建和操作 CFString 的完整示例:
extern crate CoreFoundation_sys as cf;
use std::os::raw::c_void;
use std::ptr;
fn main() {
unsafe {
// 创建一个 CFString
let string = b"Hello, CoreFoundation!\0";
let cf_string = cf::CFStringCreateWithBytes(
ptr::null(), // allocator
string.as_ptr(), // bytes
string.len() as cf::CFIndex, // length
cf::kCFStringEncodingUTF8, // encoding
0 // isExternalRepresentation
);
// 获取字符串长度
let length = cf::CFStringGetLength(cf_string);
println!("String length: {}", length);
// 检查是否包含子串
let substring = b"Core\0";
let cf_substring = cf::CFStringCreateWithBytes(
ptr::null(),
substring.as_ptr(),
substring.len() as cf::CFIndex,
cf::kCFStringEncodingUTF8,
0
);
let range = cf::CFStringFind(
cf_string,
cf_substring,
cf::kCFCompareCaseInsensitive
);
println!(
"Substring found at location: {}, length: {}",
range.location,
range.length
);
// 释放内存
cf::CFRelease(cf_string as *const c_void);
cf::CFRelease(cf_substring as *const c_void);
}
}
完整示例demo
下面是一个使用 CoreFoundation-sys 创建 CFArray 并遍历元素的完整示例:
extern crate CoreFoundation_sys as cf;
use std::os::raw::c_void;
use std::ptr;
fn main() {
unsafe {
// 创建3个CFString对象
let strings = [
b"Apple\0",
b"Banana\0",
b"Orange\0"
];
let cf_strings: Vec<*const c_void> = strings.iter().map(|s| {
let cf_str = cf::CFStringCreateWithBytes(
ptr::null(),
s.as_ptr(),
s.len() as cf::CFIndex,
cf::kCFStringEncodingUTF8,
0
);
cf_str as *const c_void
}).collect();
// 创建CFArray
let cf_array = cf::CFArrayCreate(
ptr::null(),
cf_strings.as_ptr(),
cf_strings.len() as cf::CFIndex,
&cf::kCFTypeArrayCallBacks
);
// 获取数组长度
let count = cf::CFArrayGetCount(cf_array);
println!("Array contains {} items", count);
// 遍历数组元素
for i in 0..count {
let item = cf::CFArrayGetValueAtIndex(cf_array, i);
let string_ref = item as cf::CFStringRef;
// 获取字符串长度
let length = cf::CFStringGetLength(string_ref);
// 分配缓冲区
let mut buffer = vec![0u8; length * 4 + 1];
// 转换为UTF-8字符串
let success = cf::CFStringGetCString(
string_ref,
buffer.as_mut_ptr() as *mut i8,
buffer.len() as cf::CFIndex,
cf::kCFStringEncodingUTF8
);
if success != 0 {
let c_str = std::ffi::CStr::from_ptr(buffer.as_ptr() as *const i8);
println!("Item {}: {:?}", i, c_str.to_string_lossy());
}
}
// 释放内存
for cf_str in cf_strings {
cf::CFRelease(cf_str);
}
cf::CFRelease(cf_array as *const c_void);
}
}
贡献
你可能会发现 CoreFoundation-sys
缺少一些你需要的功能。如果是这样,请在 Github 上提交 issue 或者发送包含新增功能的 pull request。
如果你计划提交 pull request,请注意代码的结构。CoreFoundation 框架中的每个头文件都有一个对应的源文件。例如,src/string.rs
包含来自 CoreFoundation/CFString.h
的定义。每个文件中的定义顺序与匹配头文件中的顺序大致相同。然后每个文件在 crate 根目录重新导出,例如 pub use string::*
。
贡献者
- dcuddeback
- oopsies49
- burtonageo
许可证
版权所有 © 2015 David Cuddeback
根据 MIT 许可证分发。
Rust系统级核心功能库CoreFoundation-sys使用指南
概述
CoreFoundation-sys是Rust的一个系统级库,提供了与Apple Core Foundation框架的底层绑定。这个库主要用于需要与macOS、iOS等Apple平台底层系统API交互的场景。
主要功能
- 提供Core Foundation框架的原始绑定
- 跨平台系统API访问
- 基础数据类型和集合类型的交互
- 内存管理和对象生命周期控制
安装方法
在Cargo.toml中添加依赖:
[dependencies]
core-foundation-sys = "0.8"
基本使用方法
1. 字符串处理
use core_foundation_sys::string::*;
unsafe {
// 创建CFString
let hello = CFStringCreateWithCString(
std::ptr::null(),
"Hello, World!\0".as_ptr() as *const i8,
kCFStringEncodingUTF8
);
// 获取字符串长度
let length = CFStringGetLength(hello);
println!("String length: {}", length);
// 释放CFString
CFRelease(hello as *const _);
}
2. 数组处理
use core_foundation_sys::array::*;
use core_foundation_sys::base::*;
unsafe {
// 创建CFArray
let values = [1 as *const _, 2 as *const _, 3 as *const _];
let array = CFArrayCreate(
std::ptr::null(),
values.as_ptr(),
values.len() as CFIndex,
&kCFTypeArrayCallBacks
);
// 获取数组元素数量
let count = CFArrayGetCount(array);
println!("Array count: {}", count);
// 释放CFArray
CFRelease(array as *const _);
}
3. 字典处理
use core_foundation_sys::dictionary::*;
use core_foundation_sys::string::*;
use core_foundation_sys::number::*;
use core_foundation_sys::base::*;
unsafe {
// 创建键和值
let keys = [CFStringCreateWithCString(
std::ptr::null(),
"name\0".as_ptr() as *const i8,
kCFStringEncodingUTF8
)];
let values = [CFNumberCreate(
std::ptr::null(),
kCFNumberSInt32Type,
&42 as *const _ as *const _
)];
// 创建CFDictionary
let dict = CFDictionaryCreate(
std::ptr::null(),
keys.as_ptr() as *const _,
values.as_ptr() as *const _,
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks
);
// 释放资源
CFRelease(keys[0] as *const _);
CFRelease(values[0] as *const _);
CFRelease(dict as *const _);
}
内存管理注意事项
CoreFoundation-sys使用手动内存管理,需要遵循Core Foundation的内存管理规则:
- 创建函数(Create/Copy)返回的对象需要手动释放
- 获取函数(Get)返回的对象通常不需要释放
- 使用
CFRetain
和CFRelease
管理引用计数
跨平台兼容性
虽然Core Foundation主要是Apple平台的框架,但CoreFoundation-sys在设计上考虑了跨平台兼容性。在非Apple平台上,某些功能可能不可用或表现不同。
高级用法
与Rust标准类型的转换
use core_foundation_sys::string::*;
use std::ffi::CString;
unsafe {
let rust_str = "Hello from Rust";
let c_str = CString::new(rust_str).unwrap();
let cf_str = CFStringCreateWithCString(
std::ptr::null(),
c_str.as_ptr(),
kCFStringEncodingUTF8
);
// 使用cf_str...
CFRelease(cf_str as *const _);
}
错误处理
use core_foundation_sys::base::*;
unsafe {
let result = some_core_foundation_function();
if result.is_null() {
// 处理错误
panic!("Core Foundation function failed");
}
// 使用result...
CFRelease(result as *const _);
}
完整示例
下面是一个整合了字符串、数组和字典处理的完整示例:
use core_foundation_sys::{
array::*,
base::*,
dictionary::*,
number::*,
string::*,
};
fn main() {
unsafe {
// 1. 字符串处理示例
let cf_str = CFStringCreateWithCString(
std::ptr::null(),
"Rust CoreFoundation示例\0".as_ptr() as *const i8,
kCFStringEncodingUTF8,
);
let length = CFStringGetLength(cf_str);
println!("字符串长度: {}", length);
// 2. 数组处理示例
let array_values = [cf_str as *const _, cf_str as *const _];
let cf_array = CFArrayCreate(
std::ptr::null(),
array_values.as_ptr(),
array_values.len() as CFIndex,
&kCFTypeArrayCallBacks,
);
let array_count = CFArrayGetCount(cf_array);
println!("数组元素数量: {}", array_count);
// 3. 字典处理示例
let keys = [CFStringCreateWithCString(
std::ptr::null(),
"language\0".as_ptr() as *const i8,
kCFStringEncodingUTF8,
)];
let values = [cf_str as *const _];
let cf_dict = CFDictionaryCreate(
std::ptr::null(),
keys.as_ptr() as *const _,
values.as_ptr() as *const _,
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks,
);
// 释放所有资源
CFRelease(keys[0] as *const _);
CFRelease(cf_str as *const _);
CFRelease(cf_array as *const _);
CFRelease(cf_dict as *const _);
}
}
总结
CoreFoundation-sys为Rust提供了与Apple系统底层API交互的能力,适合需要深度系统集成的应用开发。使用时需要注意内存管理和平台兼容性问题。