diff --git a/.gitignore b/.gitignore index f17f8155b..ec6251084 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ lib/generated_bridge.dart .vscode-server/ .ssh .devcontainer/.* +# build cache in examples +examples/**/target/ \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 28eacffce..b8c4f59f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -136,7 +136,7 @@ flutter_rust_bridge = "1.61.1" [workspace] members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display", "libs/virtual_display/dylib", "libs/simple_rc", "libs/portable"] -exclude = ["vdi/host"] +exclude = ["vdi/host", "examples/custom_plugin"] [package.metadata.winres] LegalCopyright = "Copyright © 2022 Purslane, Inc." diff --git a/examples/custom_plugin/Cargo.toml b/examples/custom_plugin/Cargo.toml new file mode 100644 index 000000000..106e48ebb --- /dev/null +++ b/examples/custom_plugin/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "custom_plugin" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +name = "custom_plugin" +path = "src/lib.rs" +crate-type = ["cdylib"] + +[dependencies] +lazy_static = "1.4.0" +rustdesk = { path = "../../", version = "1.2.0"} + +[profile.release] +lto = true +codegen-units = 1 +panic = 'abort' +strip = true +#opt-level = 'z' # only have smaller size after strip +rpath = true \ No newline at end of file diff --git a/examples/custom_plugin/src/lib.rs b/examples/custom_plugin/src/lib.rs new file mode 100644 index 000000000..be051c1d9 --- /dev/null +++ b/examples/custom_plugin/src/lib.rs @@ -0,0 +1,30 @@ +use librustdesk::{api::RustDeskApiTable}; +/// This file demonstrates how to write a custom plugin for RustDesk. +use std::ffi::{c_char, c_int, CString}; + +lazy_static::lazy_static! { + pub static ref PLUGIN_NAME: CString = CString::new("A Template Rust Plugin").unwrap(); + pub static ref PLUGIN_ID: CString = CString::new("TemplatePlugin").unwrap(); + // Do your own logic based on the API provided by RustDesk. + pub static ref API: RustDeskApiTable = RustDeskApiTable::default(); +} + +#[no_mangle] +fn plugin_name() -> *const c_char { + return PLUGIN_NAME.as_ptr(); +} + +#[no_mangle] +fn plugin_id() -> *const c_char { + return PLUGIN_ID.as_ptr(); +} + +#[no_mangle] +fn plugin_init() -> c_int { + return 0 as _; +} + +#[no_mangle] +fn plugin_dispose() -> c_int { + return 0 as _; +} diff --git a/src/api.rs b/src/api.rs index 19779995e..1c993a5ee 100644 --- a/src/api.rs +++ b/src/api.rs @@ -8,8 +8,8 @@ pub type UnloadPluginFunc = fn(*const c_char) -> i32; #[repr(C)] pub struct RustDeskApiTable { - pub register_plugin: LoadPluginFunc, - pub unload_plugin: UnloadPluginFunc, + pub(crate) register_plugin: LoadPluginFunc, + pub(crate) unload_plugin: UnloadPluginFunc, } #[no_mangle] @@ -22,11 +22,6 @@ fn unload_plugin(path: *const c_char) -> i32 { PLUGIN_REGISTRAR.unload_plugin(path) } -#[no_mangle] -fn get_api_table() -> RustDeskApiTable { - RustDeskApiTable::default() -} - impl Default for RustDeskApiTable { fn default() -> Self { Self { diff --git a/src/lib.rs b/src/lib.rs index af9f773ce..15c0ca037 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ +mod keyboard; #[cfg(not(any(target_os = "ios")))] /// cbindgen:ignore pub mod platform; -mod keyboard; #[cfg(not(any(target_os = "android", target_os = "ios")))] pub use platform::{get_cursor, get_cursor_data, get_cursor_pos, start_os_service}; #[cfg(not(any(target_os = "ios")))] @@ -20,7 +20,12 @@ pub use self::rendezvous_mediator::*; pub mod common; #[cfg(not(any(target_os = "ios")))] pub mod ipc; -#[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli", feature = "flutter")))] +#[cfg(not(any( + target_os = "android", + target_os = "ios", + feature = "cli", + feature = "flutter" +)))] pub mod ui; mod version; pub use version::*; @@ -44,9 +49,9 @@ mod license; mod port_forward; #[cfg(not(any(target_os = "android", target_os = "ios")))] -mod plugins; +pub mod api; #[cfg(not(any(target_os = "android", target_os = "ios")))] -mod api; +pub mod plugins; mod tray; diff --git a/src/plugins.rs b/src/plugins.rs index 9ca2ad8f0..3235bce4a 100644 --- a/src/plugins.rs +++ b/src/plugins.rs @@ -170,33 +170,28 @@ impl TryFrom for PluginImpl { #[cfg(target_os = "linux")] fn test_plugin() { use std::io::Write; - - let code = " - const char* plugin_name(){return \"test_name\";}; - const char* plugin_id(){return \"test_id\"; } - int plugin_init() {return 0;} - int plugin_dispose() {return 0;} - "; - let mut f = std::fs::File::create("test.c").unwrap(); - f.write_all(code.as_bytes()).unwrap(); - f.flush().unwrap(); - let mut cmd = std::process::Command::new("cc"); - cmd.arg("-fPIC") - .arg("-shared") - .arg("test.c") - .arg("-o") - .arg("libtest.so"); + let mut cmd = std::process::Command::new("cargo"); + cmd.current_dir("./examples/custom_plugin"); + // Strip this shared library. + cmd.env("RUSTFLAGS", "-C link-arg=-s"); + cmd.arg("build"); // Spawn the compiler process. let mut child = cmd.spawn().unwrap(); // Wait for the compiler to finish. let status = child.wait().unwrap(); assert!(status.success()); // Load the library. - let lib = unsafe { Library::new("./libtest.so").unwrap() }; + let lib = unsafe { + Library::new("./examples/custom_plugin/target/debug/libcustom_plugin.so").unwrap() + }; let plugin: PluginImpl = lib.try_into().unwrap(); assert!(plugin._inner.is_some()); - assert!(plugin.name == "test_name"); - assert!(plugin.id == "test_id"); + assert!(plugin.name == "A Template Rust Plugin"); + assert!(plugin.id == "TemplatePlugin"); + println!( + "plugin vt size: {}", + std::mem::size_of::() + ); assert!(PLUGIN_REGISTRAR .plugins .write()