feat: change dummy c to a rust plugin example

This commit is contained in:
Kingtous 2023-04-13 02:06:42 +08:00
parent e3c828a6f1
commit f2f39e31a1
7 changed files with 81 additions and 31 deletions

2
.gitignore vendored
View File

@ -48,3 +48,5 @@ lib/generated_bridge.dart
.vscode-server/ .vscode-server/
.ssh .ssh
.devcontainer/.* .devcontainer/.*
# build cache in examples
examples/**/target/

View File

@ -136,7 +136,7 @@ flutter_rust_bridge = "1.61.1"
[workspace] [workspace]
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display", "libs/virtual_display/dylib", "libs/simple_rc", "libs/portable"] 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] [package.metadata.winres]
LegalCopyright = "Copyright © 2022 Purslane, Inc." LegalCopyright = "Copyright © 2022 Purslane, Inc."

View File

@ -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

View File

@ -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 _;
}

View File

@ -8,8 +8,8 @@ pub type UnloadPluginFunc = fn(*const c_char) -> i32;
#[repr(C)] #[repr(C)]
pub struct RustDeskApiTable { pub struct RustDeskApiTable {
pub register_plugin: LoadPluginFunc, pub(crate) register_plugin: LoadPluginFunc,
pub unload_plugin: UnloadPluginFunc, pub(crate) unload_plugin: UnloadPluginFunc,
} }
#[no_mangle] #[no_mangle]
@ -22,11 +22,6 @@ fn unload_plugin(path: *const c_char) -> i32 {
PLUGIN_REGISTRAR.unload_plugin(path) PLUGIN_REGISTRAR.unload_plugin(path)
} }
#[no_mangle]
fn get_api_table() -> RustDeskApiTable {
RustDeskApiTable::default()
}
impl Default for RustDeskApiTable { impl Default for RustDeskApiTable {
fn default() -> Self { fn default() -> Self {
Self { Self {

View File

@ -1,7 +1,7 @@
mod keyboard;
#[cfg(not(any(target_os = "ios")))] #[cfg(not(any(target_os = "ios")))]
/// cbindgen:ignore /// cbindgen:ignore
pub mod platform; pub mod platform;
mod keyboard;
#[cfg(not(any(target_os = "android", target_os = "ios")))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
pub use platform::{get_cursor, get_cursor_data, get_cursor_pos, start_os_service}; pub use platform::{get_cursor, get_cursor_data, get_cursor_pos, start_os_service};
#[cfg(not(any(target_os = "ios")))] #[cfg(not(any(target_os = "ios")))]
@ -20,7 +20,12 @@ pub use self::rendezvous_mediator::*;
pub mod common; pub mod common;
#[cfg(not(any(target_os = "ios")))] #[cfg(not(any(target_os = "ios")))]
pub mod ipc; 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; pub mod ui;
mod version; mod version;
pub use version::*; pub use version::*;
@ -44,9 +49,9 @@ mod license;
mod port_forward; mod port_forward;
#[cfg(not(any(target_os = "android", target_os = "ios")))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
mod plugins; pub mod api;
#[cfg(not(any(target_os = "android", target_os = "ios")))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
mod api; pub mod plugins;
mod tray; mod tray;

View File

@ -170,33 +170,28 @@ impl TryFrom<Library> for PluginImpl {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
fn test_plugin() { fn test_plugin() {
use std::io::Write; use std::io::Write;
let mut cmd = std::process::Command::new("cargo");
let code = " cmd.current_dir("./examples/custom_plugin");
const char* plugin_name(){return \"test_name\";}; // Strip this shared library.
const char* plugin_id(){return \"test_id\"; } cmd.env("RUSTFLAGS", "-C link-arg=-s");
int plugin_init() {return 0;} cmd.arg("build");
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");
// Spawn the compiler process. // Spawn the compiler process.
let mut child = cmd.spawn().unwrap(); let mut child = cmd.spawn().unwrap();
// Wait for the compiler to finish. // Wait for the compiler to finish.
let status = child.wait().unwrap(); let status = child.wait().unwrap();
assert!(status.success()); assert!(status.success());
// Load the library. // 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(); let plugin: PluginImpl = lib.try_into().unwrap();
assert!(plugin._inner.is_some()); assert!(plugin._inner.is_some());
assert!(plugin.name == "test_name"); assert!(plugin.name == "A Template Rust Plugin");
assert!(plugin.id == "test_id"); assert!(plugin.id == "TemplatePlugin");
println!(
"plugin vt size: {}",
std::mem::size_of::<RustDeskPluginTable>()
);
assert!(PLUGIN_REGISTRAR assert!(PLUGIN_REGISTRAR
.plugins .plugins
.write() .write()