You've already forked example-native-api-rs
mirror of
https://github.com/medigor/example-native-api-rs.git
synced 2025-07-03 00:58:13 +02:00
разные улучшения
This commit is contained in:
@ -14,6 +14,7 @@ const PROPS: &[&[u16]] = &[
|
||||
const METHODS: &[&[u16]] = &[&utf16_null!("Method1")];
|
||||
|
||||
pub struct Addin1 {
|
||||
test: i32,
|
||||
prop_i32: i32,
|
||||
prop_f64: f64,
|
||||
prop_bool: bool,
|
||||
@ -25,6 +26,7 @@ pub struct Addin1 {
|
||||
impl Addin1 {
|
||||
pub fn new() -> Addin1 {
|
||||
Addin1 {
|
||||
test: 12345,
|
||||
prop_i32: 0,
|
||||
prop_f64: 0.0,
|
||||
prop_bool: false,
|
||||
@ -44,10 +46,6 @@ impl Addin for Addin1 {
|
||||
true
|
||||
}
|
||||
|
||||
fn get_info(&mut self) -> u16 {
|
||||
1000
|
||||
}
|
||||
|
||||
fn done(&mut self) {}
|
||||
|
||||
fn register_extension_as(&mut self) -> &'static [u16] {
|
||||
@ -68,7 +66,7 @@ impl Addin for Addin1 {
|
||||
|
||||
fn get_prop_val(&mut self, num: usize, val: ReturnValue) -> bool {
|
||||
match num {
|
||||
0 => val.set_i32(111226),
|
||||
0 => val.set_i32(self.test),
|
||||
1 => val.set_i32(self.prop_i32),
|
||||
2 => val.set_f64(self.prop_f64),
|
||||
3 => val.set_bool(self.prop_bool),
|
||||
@ -87,6 +85,13 @@ impl Addin for Addin1 {
|
||||
|
||||
fn set_prop_val(&mut self, num: usize, val: &ParamValue) -> bool {
|
||||
match num {
|
||||
0 => match val {
|
||||
ParamValue::I32(x) => {
|
||||
self.test = *x;
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
1 => match val {
|
||||
ParamValue::I32(x) => {
|
||||
self.prop_i32 = *x;
|
||||
@ -140,7 +145,7 @@ impl Addin for Addin1 {
|
||||
|
||||
fn is_prop_writable(&mut self, num: usize) -> bool {
|
||||
match num {
|
||||
0 => false,
|
||||
0 => true,
|
||||
1 => true,
|
||||
2 => true,
|
||||
3 => true,
|
||||
|
121
src/addin2.rs
Normal file
121
src/addin2.rs
Normal file
@ -0,0 +1,121 @@
|
||||
use crate::ffi::{Addin, Connection, ParamValue, ReturnValue};
|
||||
use utf16_lit::utf16_null;
|
||||
|
||||
pub struct Addin2 {
|
||||
test1: i32,
|
||||
}
|
||||
|
||||
impl Addin2 {
|
||||
pub fn new() -> Addin2 {
|
||||
Addin2 { test1: 12345 }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Addin2 {
|
||||
fn drop(&mut self) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
impl Addin for Addin2 {
|
||||
fn init(&mut self, _interface: &'static Connection) -> bool {
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn done(&mut self) {
|
||||
|
||||
}
|
||||
|
||||
fn register_extension_as(&mut self) -> &'static [u16] {
|
||||
&utf16_null!("Class2")
|
||||
}
|
||||
|
||||
fn get_n_props(&mut self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn find_prop(&mut self, name: &[u16]) -> Option<usize> {
|
||||
const TEST1: &[u16] = &utf16_null!("Test1");
|
||||
match name {
|
||||
TEST1 => Some(0),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_prop_name(&mut self, num: usize, _alias: usize) -> Option<&'static [u16]> {
|
||||
if num == 0 {
|
||||
Some(&utf16_null!("Test1"))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_prop_val(&mut self, num: usize, val: ReturnValue) -> bool {
|
||||
match num {
|
||||
0 => {
|
||||
val.set_i32(self.test1);
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_prop_val(&mut self, _num: usize, _val: &ParamValue) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn is_prop_readable(&mut self, _num: usize) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn is_prop_writable(&mut self, _num: usize) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn get_n_methods(&mut self) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
fn find_method(&mut self, _name: &[u16]) -> Option<usize> {
|
||||
None
|
||||
}
|
||||
|
||||
fn get_method_name(&mut self, _num: usize, _alias: usize) -> Option<&'static [u16]> {
|
||||
None
|
||||
}
|
||||
|
||||
fn get_n_params(&mut self, _num: usize) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
fn get_param_def_value(
|
||||
&mut self,
|
||||
_method_num: usize,
|
||||
_param_num: usize,
|
||||
_value: ReturnValue,
|
||||
) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn has_ret_val(&mut self, _method_num: usize) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn call_as_proc(&mut self, _method_num: usize, _params: &[ParamValue]) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn call_as_func(
|
||||
&mut self,
|
||||
_method_num: usize,
|
||||
_params: &[ParamValue],
|
||||
_val: ReturnValue,
|
||||
) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn set_locale(&mut self, _loc: &[u16]) {}
|
||||
|
||||
fn set_user_interface_language_code(&mut self, _lang: &[u16]) {}
|
||||
}
|
74
src/ffi.rs
74
src/ffi.rs
@ -219,7 +219,11 @@ struct TVariant {
|
||||
|
||||
pub trait Addin {
|
||||
fn init(&mut self, interface: &'static Connection) -> bool;
|
||||
fn get_info(&mut self) -> u16;
|
||||
|
||||
/// default 2000, don't use version 1000, because static objects are created
|
||||
fn get_info(&mut self) -> u16 {
|
||||
2000
|
||||
}
|
||||
fn done(&mut self);
|
||||
fn register_extension_as(&mut self) -> &'static [u16];
|
||||
fn get_n_props(&mut self) -> usize;
|
||||
@ -354,8 +358,7 @@ unsafe extern "system" fn find_prop<T: Addin>(
|
||||
component: &mut LanguageExtenderBase<T>,
|
||||
name: *const u16,
|
||||
) -> c_long {
|
||||
let len = strlen(name);
|
||||
let name = from_raw_parts(name, len);
|
||||
let name = get_str(name);
|
||||
match component.addin.find_prop(name) {
|
||||
Some(i) => i as c_long,
|
||||
None => -1,
|
||||
@ -432,8 +435,7 @@ unsafe extern "system" fn find_method<T: Addin>(
|
||||
component: &mut LanguageExtenderBase<T>,
|
||||
name: *const u16,
|
||||
) -> c_long {
|
||||
let len = strlen(name);
|
||||
let name = from_raw_parts(name, len);
|
||||
let name = get_str(name);
|
||||
match component.addin.find_method(name) {
|
||||
Some(i) => i as c_long,
|
||||
None => -1,
|
||||
@ -551,8 +553,7 @@ struct LocaleBaseVTable<T: Addin> {
|
||||
}
|
||||
|
||||
unsafe extern "system" fn set_locale<T: Addin>(component: &mut LocaleBase<T>, loc: *const u16) {
|
||||
let len = strlen(loc);
|
||||
let loc = from_raw_parts(loc, len);
|
||||
let loc = get_str(loc);
|
||||
component.addin.set_locale(loc)
|
||||
}
|
||||
|
||||
@ -570,8 +571,7 @@ unsafe extern "system" fn set_user_interface_language_code<T: Addin>(
|
||||
component: &mut UserLanguageBase<T>,
|
||||
lang: *const u16,
|
||||
) {
|
||||
let len = strlen(lang);
|
||||
let lang = from_raw_parts(lang, len);
|
||||
let lang = get_str(lang);
|
||||
component.addin.set_user_interface_language_code(lang)
|
||||
}
|
||||
|
||||
@ -588,30 +588,27 @@ struct ComponentBase<T: Addin> {
|
||||
}
|
||||
|
||||
unsafe extern "system" fn destroy<T: Addin>(component: *mut *mut ComponentBase<T>) {
|
||||
let component = unsafe { Box::from_raw(*component) };
|
||||
drop(component);
|
||||
let comp = Box::from_raw(*component);
|
||||
drop(comp);
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[allow(dead_code)]
|
||||
struct InitDoneBase<T: Addin> {
|
||||
_vptr1: Box<InitDoneBaseVTable<T>>,
|
||||
_vptr2: Box<LanguageExtenderBaseVTable<T>>,
|
||||
_vptr3: Box<LocaleBaseVTable<T>>,
|
||||
_vptr4: Box<UserLanguageBaseVTable<T>>,
|
||||
_vptr1: usize,
|
||||
_vptr2: usize,
|
||||
_vptr3: usize,
|
||||
_vptr4: usize,
|
||||
destroy: unsafe extern "system" fn(*mut *mut ComponentBase<T>),
|
||||
memory: Option<&'static MemoryManager>,
|
||||
addin: T,
|
||||
}
|
||||
|
||||
// type InitDoneBase<T> = ComponentBase<T>;
|
||||
|
||||
#[repr(C)]
|
||||
#[allow(dead_code)]
|
||||
struct LanguageExtenderBase<T: Addin> {
|
||||
_vptr2: Box<LanguageExtenderBaseVTable<T>>,
|
||||
_vptr3: Box<LocaleBaseVTable<T>>,
|
||||
_vptr4: Box<UserLanguageBaseVTable<T>>,
|
||||
_vptr2: usize,
|
||||
_vptr3: usize,
|
||||
_vptr4: usize,
|
||||
destroy: unsafe extern "system" fn(*mut *mut ComponentBase<T>),
|
||||
memory: Option<&'static MemoryManager>,
|
||||
addin: T,
|
||||
@ -620,8 +617,8 @@ struct LanguageExtenderBase<T: Addin> {
|
||||
#[repr(C)]
|
||||
#[allow(dead_code)]
|
||||
struct LocaleBase<T: Addin> {
|
||||
_vptr3: Box<LocaleBaseVTable<T>>,
|
||||
_vptr4: Box<UserLanguageBaseVTable<T>>,
|
||||
_vptr3: usize,
|
||||
_vptr4: usize,
|
||||
destroy: unsafe extern "system" fn(*mut *mut ComponentBase<T>),
|
||||
memory: Option<&'static MemoryManager>,
|
||||
addin: T,
|
||||
@ -630,13 +627,13 @@ struct LocaleBase<T: Addin> {
|
||||
#[repr(C)]
|
||||
#[allow(dead_code)]
|
||||
struct UserLanguageBase<T: Addin> {
|
||||
_vptr4: Box<UserLanguageBaseVTable<T>>,
|
||||
_vptr4: usize,
|
||||
destroy: unsafe extern "system" fn(*mut *mut ComponentBase<T>),
|
||||
memory: Option<&'static MemoryManager>,
|
||||
addin: T,
|
||||
}
|
||||
|
||||
pub fn create_component<T: Addin>(addin: T) -> *mut c_void {
|
||||
pub unsafe fn create_component<T: Addin>(component: *mut *mut c_void, addin: T) -> c_long {
|
||||
let vptr1 = Box::new(InitDoneBaseVTable {
|
||||
dtor: 0,
|
||||
#[cfg(target_family = "unix")]
|
||||
@ -693,26 +690,26 @@ pub fn create_component<T: Addin>(addin: T) -> *mut c_void {
|
||||
addin,
|
||||
});
|
||||
|
||||
let p = Box::leak(c);
|
||||
p as *mut ComponentBase<T> as *mut c_void
|
||||
*component = Box::into_raw(c) as *mut c_void;
|
||||
1
|
||||
}
|
||||
|
||||
pub fn destroy_component(component: *mut *mut c_void) {
|
||||
pub unsafe fn destroy_component(component: *mut *mut c_void) -> c_long {
|
||||
#[repr(C)]
|
||||
#[allow(dead_code)]
|
||||
struct ComponentWrapper {
|
||||
vptr1: Box<c_void>,
|
||||
vptr2: Box<c_void>,
|
||||
vptr3: Box<c_void>,
|
||||
vptr4: Box<c_void>,
|
||||
vptr1: usize,
|
||||
vptr2: usize,
|
||||
vptr3: usize,
|
||||
vptr4: usize,
|
||||
destroy: unsafe extern "system" fn(*mut *mut c_void),
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let wrapper = *component as *mut ComponentWrapper;
|
||||
let wrapper = &mut *wrapper;
|
||||
(wrapper.destroy)(component);
|
||||
}
|
||||
*component = ptr::null_mut();
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@ -759,11 +756,16 @@ pub struct Connection {
|
||||
vptr1: &'static ConnectionVTable,
|
||||
}
|
||||
|
||||
fn strlen(s: *const u16) -> usize {
|
||||
unsafe fn get_str<'a>(s: *const u16) -> &'a [u16] {
|
||||
unsafe fn strlen(s: *const u16) -> usize {
|
||||
let mut i = 0;
|
||||
while unsafe { *s.add(i) } != 0 {
|
||||
i += 1;
|
||||
}
|
||||
i += 1;
|
||||
i
|
||||
}
|
||||
|
||||
let len = strlen(s);
|
||||
from_raw_parts(s, len)
|
||||
}
|
||||
|
29
src/lib.rs
29
src/lib.rs
@ -1,8 +1,9 @@
|
||||
mod addin1;
|
||||
mod addin2;
|
||||
mod ffi;
|
||||
|
||||
use std::{
|
||||
ffi::{c_long, c_void, c_int},
|
||||
ffi::{c_int, c_long, c_void},
|
||||
sync::atomic::{AtomicI32, Ordering},
|
||||
};
|
||||
|
||||
@ -10,36 +11,42 @@ use addin1::Addin1;
|
||||
use ffi::{destroy_component, AttachType};
|
||||
use utf16_lit::utf16_null;
|
||||
|
||||
use crate::ffi::create_component;
|
||||
use crate::{addin2::Addin2, ffi::create_component};
|
||||
|
||||
pub static mut PLATFORM_CAPABILITIES: AtomicI32 = AtomicI32::new(-1);
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn GetClassObject(_name: *const u16, component: *mut *mut c_void) -> c_long {
|
||||
pub unsafe extern "C" fn GetClassObject(name: *const u16, component: *mut *mut c_void) -> c_long {
|
||||
match *name as u8 {
|
||||
b'1' => {
|
||||
let addin = Addin1::new();
|
||||
unsafe {
|
||||
*component = create_component(addin);
|
||||
create_component(component, addin)
|
||||
}
|
||||
b'2' => {
|
||||
let addin = Addin2::new();
|
||||
create_component(component, addin)
|
||||
}
|
||||
_ => 0,
|
||||
}
|
||||
1
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn DestroyObject(component: *mut *mut c_void) -> c_long {
|
||||
destroy_component(component);
|
||||
0
|
||||
pub unsafe extern "C" fn DestroyObject(component: *mut *mut c_void) -> c_long {
|
||||
destroy_component(component)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn GetClassNames() -> *const u16 {
|
||||
utf16_null!("Class1").as_ptr()
|
||||
// small strings for performance
|
||||
utf16_null!("1|2").as_ptr()
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn SetPlatformCapabilities(capabilities: c_int) -> c_long {
|
||||
pub extern "C" fn SetPlatformCapabilities(capabilities: c_int) -> c_int {
|
||||
unsafe {
|
||||
PLATFORM_CAPABILITIES.store(capabilities, Ordering::Relaxed);
|
||||
}
|
||||
|
Reference in New Issue
Block a user