plugin_interfaces/
symbols.rs

1use crate::callbacks::HostCallbacks;
2use crate::metadata::{PluginInstanceContext, PluginMetadataFFI};
3use std::os::raw::c_char;
4
5/// 插件包装器,包含处理器和上下文
6pub struct PluginWrapper {
7    pub handler: Box<dyn crate::handler::PluginHandler>,
8    pub context: Option<PluginInstanceContext>,
9}
10
11/// FFI安全的插件接口
12/// 使用C风格的函数指针而不是trait对象
13#[repr(C)]
14pub struct PluginInterface {
15    pub plugin_ptr: *mut std::ffi::c_void,
16    pub initialize:
17        unsafe extern "C" fn(*mut std::ffi::c_void, HostCallbacks, PluginMetadataFFI) -> i32,
18    pub update_ui: unsafe extern "C" fn(
19        *mut std::ffi::c_void,
20        *const std::ffi::c_void,
21        *mut std::ffi::c_void,
22    ) -> i32,
23    pub on_mount: unsafe extern "C" fn(*mut std::ffi::c_void) -> i32,
24    pub on_dispose: unsafe extern "C" fn(*mut std::ffi::c_void) -> i32,
25    pub on_connect: unsafe extern "C" fn(*mut std::ffi::c_void) -> i32,
26    pub on_disconnect: unsafe extern "C" fn(*mut std::ffi::c_void) -> i32,
27    pub handle_message:
28        unsafe extern "C" fn(*mut std::ffi::c_void, *const c_char, *mut *mut c_char) -> i32,
29    pub get_metadata: unsafe extern "C" fn(*mut std::ffi::c_void) -> PluginMetadataFFI,
30    pub destroy: unsafe extern "C" fn(*mut std::ffi::c_void),
31}
32
33/// 插件创建函数类型
34/// 返回FFI安全的插件接口
35pub type CreatePluginFn = unsafe extern "C" fn() -> *mut PluginInterface;
36
37/// 插件销毁函数类型
38/// 销毁插件接口
39pub type DestroyPluginFn = unsafe extern "C" fn(*mut PluginInterface);
40
41/// 插件导出符号名称
42pub const CREATE_PLUGIN_SYMBOL: &[u8] = b"create_plugin";
43pub const DESTROY_PLUGIN_SYMBOL: &[u8] = b"destroy_plugin";
44
45/// 从PluginHandler trait对象创建FFI安全的插件接口
46/// 这个函数帮助插件开发者将trait对象转换为FFI安全的接口
47pub fn create_plugin_interface_from_handler(
48    handler: Box<dyn crate::handler::PluginHandler>,
49) -> *mut PluginInterface {
50    use std::ffi::{CStr, CString};
51
52    let wrapper = PluginWrapper {
53        handler,
54        context: None,
55    };
56    let wrapper_ptr = Box::into_raw(Box::new(wrapper)) as *mut std::ffi::c_void;
57
58    // 定义FFI安全的函数包装器
59    unsafe extern "C" fn initialize_wrapper(
60        ptr: *mut std::ffi::c_void,
61        callbacks: HostCallbacks,
62        metadata_ffi: PluginMetadataFFI,
63    ) -> i32 {
64        let wrapper = &mut *(ptr as *mut PluginWrapper);
65
66        // 将 FFI 元数据转换为 Rust 元数据
67        let metadata = crate::metadata::convert_ffi_to_metadata(metadata_ffi);
68
69        match wrapper.handler.initialize(callbacks, metadata) {
70            Ok(context) => {
71                wrapper.context = Some(context);
72                0
73            }
74            Err(_) => -1,
75        }
76    }
77
78    unsafe extern "C" fn update_ui_wrapper(
79        ptr: *mut std::ffi::c_void,
80        ctx_ptr: *const std::ffi::c_void,
81        ui_ptr: *mut std::ffi::c_void,
82    ) -> i32 {
83        let wrapper = &mut *(ptr as *mut PluginWrapper);
84        let ctx = &*(ctx_ptr as *const crate::pluginui::Context);
85        let ui = &mut *(ui_ptr as *mut crate::pluginui::Ui);
86
87        if let Some(plugin_context) = &wrapper.context {
88            wrapper.handler.update_ui(ctx, ui, plugin_context);
89        }
90        0
91    }
92
93    unsafe extern "C" fn on_mount_wrapper(ptr: *mut std::ffi::c_void) -> i32 {
94        let wrapper = &mut *(ptr as *mut PluginWrapper);
95
96        if let Some(plugin_context) = &wrapper.context {
97            match wrapper.handler.on_mount(plugin_context) {
98                Ok(_) => 0,
99                Err(_) => -1,
100            }
101        } else {
102            -1
103        }
104    }
105
106    unsafe extern "C" fn on_dispose_wrapper(ptr: *mut std::ffi::c_void) -> i32 {
107        let wrapper = &mut *(ptr as *mut PluginWrapper);
108        if let Some(plugin_context) = &wrapper.context {
109            match wrapper.handler.on_dispose(plugin_context) {
110                Ok(_) => 0,
111                Err(_) => -1,
112            }
113        } else {
114            -1
115        }
116    }
117
118    unsafe extern "C" fn on_connect_wrapper(ptr: *mut std::ffi::c_void) -> i32 {
119        let wrapper = &mut *(ptr as *mut PluginWrapper);
120        if let Some(plugin_context) = &wrapper.context {
121            match wrapper.handler.on_connect(plugin_context) {
122                Ok(_) => 0,
123                Err(_) => -1,
124            }
125        } else {
126            -1
127        }
128    }
129
130    unsafe extern "C" fn on_disconnect_wrapper(ptr: *mut std::ffi::c_void) -> i32 {
131        let wrapper = &mut *(ptr as *mut PluginWrapper);
132        if let Some(plugin_context) = &wrapper.context {
133            match wrapper.handler.on_disconnect(plugin_context) {
134                Ok(_) => 0,
135                Err(_) => -1,
136            }
137        } else {
138            -1
139        }
140    }
141
142    unsafe extern "C" fn handle_message_wrapper(
143        ptr: *mut std::ffi::c_void,
144        message: *const c_char,
145        result: *mut *mut c_char,
146    ) -> i32 {
147        let wrapper = &mut *(ptr as *mut PluginWrapper);
148        let message_str = CStr::from_ptr(message).to_string_lossy();
149
150        if let Some(plugin_context) = &wrapper.context {
151            match wrapper.handler.handle_message(&message_str, plugin_context) {
152                Ok(response) => {
153                    let response_cstring = CString::new(response).unwrap();
154                    *result = response_cstring.into_raw();
155                    0
156                }
157                Err(_) => -1,
158            }
159        } else {
160            -1
161        }
162    }
163
164    unsafe extern "C" fn get_metadata_wrapper(ptr: *mut std::ffi::c_void) -> PluginMetadataFFI {
165        let wrapper = &*(ptr as *mut PluginWrapper);
166        if let Some(plugin_context) = &wrapper.context {
167            let metadata = wrapper.handler.get_metadata(plugin_context);
168            metadata.to_ffi()
169        } else {
170            // 返回一个默认的空元数据
171            PluginMetadataFFI {
172                id: std::ptr::null(),
173                disabled: false,
174                name: std::ptr::null(),
175                description: std::ptr::null(),
176                version: std::ptr::null(),
177                author: std::ptr::null(),
178                library_path: std::ptr::null(),
179                config_path: std::ptr::null(),
180                instance_id: std::ptr::null(),
181            }
182        }
183    }
184
185    unsafe extern "C" fn destroy_wrapper(ptr: *mut std::ffi::c_void) {
186        let _ = Box::from_raw(ptr as *mut PluginWrapper);
187    }
188
189    let interface = PluginInterface {
190        plugin_ptr: wrapper_ptr,
191        initialize: initialize_wrapper,
192        update_ui: update_ui_wrapper,
193        on_mount: on_mount_wrapper,
194        on_dispose: on_dispose_wrapper,
195        on_connect: on_connect_wrapper,
196        on_disconnect: on_disconnect_wrapper,
197        handle_message: handle_message_wrapper,
198        get_metadata: get_metadata_wrapper,
199        destroy: destroy_wrapper,
200    };
201
202    Box::into_raw(Box::new(interface))
203}