moon add Qisu-dev/ffi| 模块 | 内容 |
|---|---|
| memory | malloc calloc realloc free |
| mem | memcpy memmove memset memcmp |
| ptr | is_null null_ptr ptr_add bytes_as_ptr fixed_array_as_ptr |
| str | strlen strcmp strcpy strdup bytes_to_cstr cstr_to_string |
| errno | errno_get errno_set strerror enoent eacces 等 |
| file | open close read write lseek pipe dup |
| mmap | mmap munmap(POSIX)、create_file_mapping map_view_of_file unmap_view_of_file(Windows) |
fn main {
// 分配内存
let buf = @ffi.malloc(1024)
if @ffi.is_null(buf) { return }
defer @ffi.free(buf)
// 写文件
let cpath = @ffi.string_to_cstr("out.txt")
defer @ffi.free(cpath)
let fd = @ffi.open(cpath, @ffi.o_wronly() | @ffi.o_creat(), 0o644)
defer { @ffi.close(fd); () }
@ffi.write(fd, @ffi.bytes_as_ptr(b"hello"), 5)
// 错误处理
if fd < 0 {
let err = @ffi.errno_get()
println(@ffi.cstr_to_string(@ffi.strerror(err)))
}
}#cfg(not(platform="windows"))
fn mmap_read(name : String) -> Unit raise {
let cpath = @ffi.string_to_cstr(name)
defer @ffi.free(cpath)
let fd = @ffi.open(cpath, @ffi.o_rdonly(), 0)
if fd < 0 { raise Failure("open failed") }
defer { @ffi.close(fd); () }
let fstate = @ffi.fstat(fd)
if @ffi.is_null(fstate) { raise Failure("fstat failed") }
defer @ffi.free(fstate)
let size = @ffi.fstat_size(fstate).reinterpret_as_uint64()
if size == 0 { return }
let addr = @ffi.mmap(
@ffi.null_ptr(), size,
@ffi.prot_read(), @ffi.map_private(),
fd, 0,
)
if addr == @ffi.map_failed() {
raise Failure("mmap failed")
}
defer ignore(@ffi.munmap(addr, size))
// addr 是只读的连续内存,可直接处理
ignore(addr)
}fn abort() -> Unitfn exit(code : Int) -> Unitfn map_shared() -> Intlet cstr_ptr = bytes_to_cstr(b"hello", 5)
defer free_cstr(cstr_ptr)
let dst = malloc(6)
defer free(dst)
strncpy(dst, cstr_ptr, 5)
memset(ptr_add(dst, 5), 0, 1)Install
Download zip