├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── my-interface ├── Cargo.toml └── src │ └── lib.rs ├── my-master ├── Cargo.toml └── src │ └── main.rs └── my-plugin ├── Cargo.toml └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "c2-chacha" 5 | version = "0.2.3" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | dependencies = [ 8 | "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 9 | ] 10 | 11 | [[package]] 12 | name = "cc" 13 | version = "1.0.47" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | 16 | [[package]] 17 | name = "cfg-if" 18 | version = "0.1.10" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | 21 | [[package]] 22 | name = "getrandom" 23 | version = "0.1.13" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | dependencies = [ 26 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 27 | "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", 28 | "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 29 | ] 30 | 31 | [[package]] 32 | name = "libc" 33 | version = "0.2.66" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | 36 | [[package]] 37 | name = "libloading" 38 | version = "0.5.2" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | dependencies = [ 41 | "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", 42 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 43 | ] 44 | 45 | [[package]] 46 | name = "my-interface" 47 | version = "0.1.0" 48 | 49 | [[package]] 50 | name = "my-master" 51 | version = "0.1.0" 52 | dependencies = [ 53 | "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 54 | "my-interface 0.1.0", 55 | ] 56 | 57 | [[package]] 58 | name = "my-plugin" 59 | version = "0.1.0" 60 | dependencies = [ 61 | "my-interface 0.1.0", 62 | "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 63 | ] 64 | 65 | [[package]] 66 | name = "ppv-lite86" 67 | version = "0.2.6" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | 70 | [[package]] 71 | name = "rand" 72 | version = "0.7.2" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | dependencies = [ 75 | "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 76 | "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", 77 | "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 78 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 79 | "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 80 | ] 81 | 82 | [[package]] 83 | name = "rand_chacha" 84 | version = "0.2.1" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | dependencies = [ 87 | "c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 88 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 89 | ] 90 | 91 | [[package]] 92 | name = "rand_core" 93 | version = "0.5.1" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | dependencies = [ 96 | "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 97 | ] 98 | 99 | [[package]] 100 | name = "rand_hc" 101 | version = "0.2.0" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | dependencies = [ 104 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 105 | ] 106 | 107 | [[package]] 108 | name = "wasi" 109 | version = "0.7.0" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | 112 | [[package]] 113 | name = "winapi" 114 | version = "0.3.8" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | dependencies = [ 117 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 118 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 119 | ] 120 | 121 | [[package]] 122 | name = "winapi-i686-pc-windows-gnu" 123 | version = "0.4.0" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | 126 | [[package]] 127 | name = "winapi-x86_64-pc-windows-gnu" 128 | version = "0.4.0" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | 131 | [metadata] 132 | "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" 133 | "checksum cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8" 134 | "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 135 | "checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" 136 | "checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" 137 | "checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" 138 | "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" 139 | "checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" 140 | "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" 141 | "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 142 | "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 143 | "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" 144 | "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 145 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 146 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 147 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "my-master", 4 | "my-plugin", 5 | "my-interface" 6 | ] 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # plugin-system-example 2 | Example design of executable with `dylib`-based runtime plugin system in Rust, `libloading` used 3 | 4 | # Usage 5 | 6 | 1. Compile plugin using `cargo build -p my-plugin` 7 | 2. Run master by `cargo run -p my-master` 8 | -------------------------------------------------------------------------------- /my-interface/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "my-interface" 3 | version = "0.1.0" 4 | authors = ["luojia65 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /my-interface/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub trait SayHelloService { 2 | fn say_hello(&self); 3 | } 4 | 5 | -------------------------------------------------------------------------------- /my-master/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "my-master" 3 | version = "0.1.0" 4 | authors = ["luojia65 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | libloading = "0.5" 11 | my-interface = { path = "../my-interface", version = "*" } 12 | -------------------------------------------------------------------------------- /my-master/src/main.rs: -------------------------------------------------------------------------------- 1 | use my_interface::SayHelloService; 2 | 3 | fn main() { 4 | let lib = libloading::Library::new("target/debug/my_plugin.dll") 5 | .expect("load library"); 6 | let new_service: libloading::Symbol Box> = unsafe { lib.get(b"new_service") } 7 | .expect("load symbol"); 8 | let service = new_service(); 9 | service.say_hello(); 10 | let service = new_service(); 11 | service.say_hello(); 12 | } 13 | -------------------------------------------------------------------------------- /my-plugin/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "my-plugin" 3 | version = "0.1.0" 4 | authors = ["luojia65 "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | my-interface = { path = "../my-interface", version = "*" } 11 | rand = "*" 12 | 13 | [lib] 14 | name = "my_plugin" 15 | crate-type = ["dylib"] 16 | -------------------------------------------------------------------------------- /my-plugin/src/lib.rs: -------------------------------------------------------------------------------- 1 | use my_interface::SayHelloService; 2 | 3 | #[no_mangle] 4 | pub extern "Rust" fn new_service() -> Box { 5 | Box::new(PluginSayHello::new()) 6 | } 7 | 8 | pub struct PluginSayHello { 9 | id: String, 10 | } 11 | 12 | impl PluginSayHello { 13 | fn new() -> PluginSayHello { 14 | let id = format!("{:08x}", rand::random::()); 15 | println!("[{}] Created instance!", id); 16 | PluginSayHello { id } 17 | } 18 | } 19 | 20 | impl SayHelloService for PluginSayHello { 21 | fn say_hello(&self) { 22 | println!("[{}] Hello from plugin!", self.id); 23 | } 24 | } 25 | 26 | impl Drop for PluginSayHello { 27 | fn drop(&mut self) { 28 | println!("[{}] Destroyed instance!", self.id); 29 | } 30 | } 31 | --------------------------------------------------------------------------------