doc:Rust-to-LLGO-Migration-Guide.md

This commit is contained in:
luoliwoshang
2024-07-14 18:12:21 +08:00
committed by 赵英杰
parent 1eb9775f34
commit 400197def8

View File

@@ -0,0 +1,125 @@
# Rust to LLGO Migration Document
### Add Dependencies & Build Configuration
Edit `Cargo.toml` to include necessary dependencies and configuration:
```toml
[dependencies]
libc = "0.2"
csv = "1.1"
[lib]
crate-type = ["cdylib"] # The generated dynamic library will conform to the C standard
```
### Import C Language Types
Use types from the libc package for interoperability with C:
```rust
use libc::{c_int, c_char, strlen};
```
### Function Decoration and Attributes
To ensure that Rust functions can be correctly called by C and LLGO, use the following decorators:
- `#[no_mangle]` prevents the compiler from mangling the function name.
- `unsafe` is used to mark operations that are unsafe, especially when dealing with raw pointers.
- `extern "C"` specifies the use of C calling conventions.
### Memory Management
Use `Box` to manage dynamic memory to ensure correct memory release between Rust and C:
```rust
pub unsafe extern "C" fn sled_create_config() -> \*mut Config {
Box::into_raw(Box::new(Config::new()))
}
#[no_mangle]
pub unsafe extern "C" fn sled_free_config(config: \*mut Config) {
drop(Box::from_raw(config));
}
```
### Handling Generic Pointers
Address the interfacing issues between generic pointers in C and Rust:
```rust
#[no_mangle]
pub extern "C" fn csv_reader_new(file_path: *const c_char) -> *mut c_void { /* ... */ }
#[no_mangle]
pub extern "C" fn csv_reader_free(ptr: *mut c_void) { /* ... */ }
```
### String Handling
Convert strings between C and Rust:
```rust
#[no_mangle]
pub extern "C" fn csv_reader_read_record(ptr: *mut c_void) -> *const c_char { /* ... */ }
#[no_mangle]
pub extern "C" fn free_string(s: *mut c_char) {
unsafe {
let c_string = CString::from_raw(s);
drop(c_string);
}
}
```
### Compilation and Installation
Build the dynamic library and use `dylib-installer` to install it to the system path:
```sh
cargo build --release
cargo install --git https://github.com/hackerchai/dylib-installer
sudo dylib_installer ./target/release/
```
### Generate Header File
Use cbindgen to generate a C header file, automating this process through a `build.rs` script:
```rust
fn main() {
let config = cbindgen::Config::from_file("cbindgen.toml").expect("Config file not found.");
cbindgen::generate_with_config(&crate_dir, config).unwrap().write_to_file("target/include/csv_wrapper.h");
}
```
### LLGO Package Mapping
Map functions from the Rust library to an LLGO package, ensuring type consistency:
```go
const (
LLGoPackage = "link: $(pkg-config --libs csv_wrapper); -lcsv_wrapper"
)
type Reader struct {
Unused [8]byte
}
//go:linkname NewReader C.csv_reader_new
func NewReader(file_path *c.Char) *Reader
//llgo:link (*Reader).Free C.csv_reader_free
func (reader *Reader) Free() {}
//llgo:link (*Reader).ReadRecord C.csv_reader_read_record
func (reader *Reader) ReadRecord() *c.Char { return nil }
```
### Writing Examples and README
Provide example code and a detailed README file to help users understand how to use the generated library.