plugin_interfaces/
symbols.rs1use crate::metadata::PluginMetadataFFI;
2use crate::callbacks::HostCallbacks;
3use std::os::raw::c_char;
4
5#[repr(C)]
8pub struct PluginInterface {
9 pub plugin_ptr: *mut std::ffi::c_void,
10 pub initialize: unsafe extern "C" fn(*mut std::ffi::c_void, HostCallbacks) -> i32,
11 pub update_ui: unsafe extern "C" fn(*mut std::ffi::c_void, *const std::ffi::c_void, *mut std::ffi::c_void) -> i32,
12 pub on_mount: unsafe extern "C" fn(*mut std::ffi::c_void, PluginMetadataFFI) -> i32,
13 pub on_dispose: unsafe extern "C" fn(*mut std::ffi::c_void) -> i32,
14 pub on_connect: unsafe extern "C" fn(*mut std::ffi::c_void) -> i32,
15 pub on_disconnect: unsafe extern "C" fn(*mut std::ffi::c_void) -> i32,
16 pub handle_message: unsafe extern "C" fn(*mut std::ffi::c_void, *const c_char, *mut *mut c_char) -> i32,
17 pub get_metadata: unsafe extern "C" fn(*mut std::ffi::c_void) -> PluginMetadataFFI,
18 pub destroy: unsafe extern "C" fn(*mut std::ffi::c_void),
19}
20
21pub type CreatePluginFn = unsafe extern "C" fn() -> *mut PluginInterface;
24
25pub type DestroyPluginFn = unsafe extern "C" fn(*mut PluginInterface);
28
29pub const CREATE_PLUGIN_SYMBOL: &[u8] = b"create_plugin";
31pub const DESTROY_PLUGIN_SYMBOL: &[u8] = b"destroy_plugin";
32
33pub fn create_plugin_interface_from_handler(
36 handler: Box<dyn crate::handler::PluginHandler>
37) -> *mut PluginInterface {
38 use std::ffi::{CStr, CString};
39
40 let handler_ptr = Box::into_raw(Box::new(handler)) as *mut std::ffi::c_void;
41
42 unsafe extern "C" fn initialize_wrapper(ptr: *mut std::ffi::c_void, callbacks: HostCallbacks) -> i32 {
44 let handler = &*(ptr as *mut Box<dyn crate::handler::PluginHandler>);
45 match handler.initialize(callbacks) {
46 Ok(_) => 0,
47 Err(_) => -1,
48 }
49 }
50
51 unsafe extern "C" fn update_ui_wrapper(
52 ptr: *mut std::ffi::c_void,
53 ctx_ptr: *const std::ffi::c_void,
54 ui_ptr: *mut std::ffi::c_void
55 ) -> i32 {
56 let handler = &mut *(ptr as *mut Box<dyn crate::handler::PluginHandler>);
57 let ctx = &*(ctx_ptr as *const crate::pluginui::Context);
58 let ui = &mut *(ui_ptr as *mut crate::pluginui::Ui);
59
60 handler.update_ui(ctx, ui);
61 0
62 }
63
64 unsafe extern "C" fn on_mount_wrapper(ptr: *mut std::ffi::c_void, metadata_ffi: PluginMetadataFFI) -> i32 {
65 let handler = &mut *(ptr as *mut Box<dyn crate::handler::PluginHandler>);
66
67 let metadata = crate::metadata::PluginMetadata {
69 id: if !metadata_ffi.id.is_null() {
70 CStr::from_ptr(metadata_ffi.id).to_string_lossy().to_string()
71 } else {
72 String::new()
73 },
74 disabled: metadata_ffi.disabled,
75 name: if !metadata_ffi.name.is_null() {
76 CStr::from_ptr(metadata_ffi.name).to_string_lossy().to_string()
77 } else {
78 String::new()
79 },
80 description: if !metadata_ffi.description.is_null() {
81 CStr::from_ptr(metadata_ffi.description).to_string_lossy().to_string()
82 } else {
83 String::new()
84 },
85 version: if !metadata_ffi.version.is_null() {
86 CStr::from_ptr(metadata_ffi.version).to_string_lossy().to_string()
87 } else {
88 String::new()
89 },
90 author: if !metadata_ffi.author.is_null() {
91 Some(CStr::from_ptr(metadata_ffi.author).to_string_lossy().to_string())
92 } else {
93 None
94 },
95 library_path: if !metadata_ffi.library_path.is_null() {
96 Some(CStr::from_ptr(metadata_ffi.library_path).to_string_lossy().to_string())
97 } else {
98 None
99 },
100 config_path: if !metadata_ffi.config_path.is_null() {
101 CStr::from_ptr(metadata_ffi.config_path).to_string_lossy().to_string()
102 } else {
103 String::new()
104 },
105 };
106
107 match handler.on_mount(&metadata) {
108 Ok(_) => 0,
109 Err(_) => -1,
110 }
111 }
112
113 unsafe extern "C" fn on_dispose_wrapper(ptr: *mut std::ffi::c_void) -> i32 {
114 let handler = &mut *(ptr as *mut Box<dyn crate::handler::PluginHandler>);
115 match handler.on_dispose() {
116 Ok(_) => 0,
117 Err(_) => -1,
118 }
119 }
120
121 unsafe extern "C" fn on_connect_wrapper(ptr: *mut std::ffi::c_void) -> i32 {
122 let handler = &mut *(ptr as *mut Box<dyn crate::handler::PluginHandler>);
123 match handler.on_connect() {
124 Ok(_) => 0,
125 Err(_) => -1,
126 }
127 }
128
129 unsafe extern "C" fn on_disconnect_wrapper(ptr: *mut std::ffi::c_void) -> i32 {
130 let handler = &mut *(ptr as *mut Box<dyn crate::handler::PluginHandler>);
131 match handler.on_disconnect() {
132 Ok(_) => 0,
133 Err(_) => -1,
134 }
135 }
136
137 unsafe extern "C" fn handle_message_wrapper(
138 ptr: *mut std::ffi::c_void,
139 message: *const c_char,
140 result: *mut *mut c_char
141 ) -> i32 {
142 let handler = &*(ptr as *mut Box<dyn crate::handler::PluginHandler>);
143 let message_str = CStr::from_ptr(message).to_string_lossy();
144
145 match handler.handle_message(&message_str) {
146 Ok(response) => {
147 let response_cstring = CString::new(response).unwrap();
148 *result = response_cstring.into_raw();
149 0
150 }
151 Err(_) => -1,
152 }
153 }
154
155 unsafe extern "C" fn get_metadata_wrapper(ptr: *mut std::ffi::c_void) -> PluginMetadataFFI {
156 let handler = &*(ptr as *mut Box<dyn crate::handler::PluginHandler>);
157 let metadata = handler.get_metadata();
158 metadata.to_ffi()
159 }
160
161 unsafe extern "C" fn destroy_wrapper(ptr: *mut std::ffi::c_void) {
162 let _ = Box::from_raw(ptr as *mut Box<dyn crate::handler::PluginHandler>);
163 }
164
165 let interface = PluginInterface {
166 plugin_ptr: handler_ptr,
167 initialize: initialize_wrapper,
168 update_ui: update_ui_wrapper,
169 on_mount: on_mount_wrapper,
170 on_dispose: on_dispose_wrapper,
171 on_connect: on_connect_wrapper,
172 on_disconnect: on_disconnect_wrapper,
173 handle_message: handle_message_wrapper,
174 get_metadata: get_metadata_wrapper,
175 destroy: destroy_wrapper,
176 };
177
178 Box::into_raw(Box::new(interface))
179}