mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-02 11:06:14 +00:00
feat: impl C ffi
This commit is contained in:
parent
a26d4b0122
commit
95309db710
5 changed files with 70 additions and 33 deletions
2
crates/loro-ffi/.gitignore
vendored
Normal file
2
crates/loro-ffi/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
examples/cpp/loro
|
||||||
|
examples/cpp/*.a
|
|
@ -1,35 +1,8 @@
|
||||||
extern crate cbindgen;
|
|
||||||
|
|
||||||
use cbindgen::Config;
|
|
||||||
use std::env;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||||
|
let config = cbindgen::Config::from_file("cbindgen.toml")
|
||||||
let package_name = env::var("CARGO_PKG_NAME").unwrap();
|
.expect("Unable to find cbindgen.toml configuration file");
|
||||||
let output_file = target_dir()
|
|
||||||
.join(format!("{}.hpp", package_name))
|
|
||||||
.display()
|
|
||||||
.to_string();
|
|
||||||
|
|
||||||
let config = Config {
|
|
||||||
namespace: Some(String::from("loro_ffi")),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
cbindgen::generate_with_config(&crate_dir, config)
|
cbindgen::generate_with_config(&crate_dir, config)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.write_to_file(&output_file);
|
.write_to_file("target/loro_ffi.h");
|
||||||
}
|
|
||||||
|
|
||||||
/// Find the location of the `target/` directory. Note that this may be
|
|
||||||
/// overridden by `cmake`, so we also need to check the `CARGO_TARGET_DIR`
|
|
||||||
/// variable.
|
|
||||||
fn target_dir() -> PathBuf {
|
|
||||||
if let Ok(target) = env::var("CARGO_TARGET_DIR") {
|
|
||||||
PathBuf::from(target)
|
|
||||||
} else {
|
|
||||||
PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join("target")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
include_guard = "libloro_ffi_h"
|
header = """
|
||||||
|
typedef struct LoroCore {} LoroCore;
|
||||||
|
|
||||||
|
typedef struct Text {} Text;
|
||||||
|
"""
|
||||||
autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
|
autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
|
||||||
language = "C"
|
language = "C"
|
||||||
|
|
14
crates/loro-ffi/examples/cpp/loro.cpp
Normal file
14
crates/loro-ffi/examples/cpp/loro.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
extern "C" {
|
||||||
|
#include "../../target/loro_ffi.h"
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
LoroCore* loro = loro_new();
|
||||||
|
Text* text = loro_get_text(loro, "text");
|
||||||
|
text_insert(text, loro, 0, "abc");
|
||||||
|
char* str = text_value(text);
|
||||||
|
printf("%s", str);
|
||||||
|
text_free(text);
|
||||||
|
loro_free(loro);
|
||||||
|
}
|
|
@ -1,4 +1,9 @@
|
||||||
use loro_core::LoroCore;
|
use std::ffi::{c_char, c_uint, CStr, CString};
|
||||||
|
|
||||||
|
pub type LoroCore = loro_core::LoroCore;
|
||||||
|
pub type Text = loro_core::Text;
|
||||||
|
pub type List = loro_core::List;
|
||||||
|
pub type Map = loro_core::Map;
|
||||||
|
|
||||||
/// create Loro with a random unique client id
|
/// create Loro with a random unique client id
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -13,3 +18,42 @@ pub unsafe extern "C" fn loro_free(loro: *mut LoroCore) {
|
||||||
drop(Box::from_raw(loro));
|
drop(Box::from_raw(loro));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn loro_get_text(loro: *mut LoroCore, id: *const c_char) -> *mut Text {
|
||||||
|
assert!(!loro.is_null());
|
||||||
|
assert!(!id.is_null());
|
||||||
|
let id = CStr::from_ptr(id).to_str().unwrap();
|
||||||
|
let text = loro.as_mut().unwrap().get_text(id);
|
||||||
|
Box::into_raw(Box::new(text))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn text_free(text: *mut Text) {
|
||||||
|
if !text.is_null() {
|
||||||
|
drop(Box::from_raw(text));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn text_insert(
|
||||||
|
text: *mut Text,
|
||||||
|
ctx: *const LoroCore,
|
||||||
|
pos: *const c_uint,
|
||||||
|
value: *const c_char,
|
||||||
|
) {
|
||||||
|
assert!(!text.is_null());
|
||||||
|
assert!(!ctx.is_null());
|
||||||
|
let text = text.as_mut().unwrap();
|
||||||
|
let ctx = ctx.as_ref().unwrap();
|
||||||
|
let value = CStr::from_ptr(value).to_str().unwrap();
|
||||||
|
text.insert(ctx, pos as usize, value).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn text_value(text: *mut Text) -> *mut c_char {
|
||||||
|
assert!(!text.is_null());
|
||||||
|
let text = text.as_mut().unwrap();
|
||||||
|
let value = text.get_value().as_string().unwrap().to_string();
|
||||||
|
CString::new(value).unwrap().into_raw()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue