feat: change dummy c to a rust plugin example
This commit is contained in:
parent
e3c828a6f1
commit
f2f39e31a1
2
.gitignore
vendored
2
.gitignore
vendored
@ -48,3 +48,5 @@ lib/generated_bridge.dart
|
|||||||
.vscode-server/
|
.vscode-server/
|
||||||
.ssh
|
.ssh
|
||||||
.devcontainer/.*
|
.devcontainer/.*
|
||||||
|
# build cache in examples
|
||||||
|
examples/**/target/
|
@ -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."
|
||||||
|
23
examples/custom_plugin/Cargo.toml
Normal file
23
examples/custom_plugin/Cargo.toml
Normal 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
|
30
examples/custom_plugin/src/lib.rs
Normal file
30
examples/custom_plugin/src/lib.rs
Normal 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 _;
|
||||||
|
}
|
@ -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 {
|
||||||
|
13
src/lib.rs
13
src/lib.rs
@ -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;
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user