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")];
|
const METHODS: &[&[u16]] = &[&utf16_null!("Method1")];
|
||||||
|
|
||||||
pub struct Addin1 {
|
pub struct Addin1 {
|
||||||
|
test: i32,
|
||||||
prop_i32: i32,
|
prop_i32: i32,
|
||||||
prop_f64: f64,
|
prop_f64: f64,
|
||||||
prop_bool: bool,
|
prop_bool: bool,
|
||||||
@ -25,6 +26,7 @@ pub struct Addin1 {
|
|||||||
impl Addin1 {
|
impl Addin1 {
|
||||||
pub fn new() -> Addin1 {
|
pub fn new() -> Addin1 {
|
||||||
Addin1 {
|
Addin1 {
|
||||||
|
test: 12345,
|
||||||
prop_i32: 0,
|
prop_i32: 0,
|
||||||
prop_f64: 0.0,
|
prop_f64: 0.0,
|
||||||
prop_bool: false,
|
prop_bool: false,
|
||||||
@ -44,10 +46,6 @@ impl Addin for Addin1 {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_info(&mut self) -> u16 {
|
|
||||||
1000
|
|
||||||
}
|
|
||||||
|
|
||||||
fn done(&mut self) {}
|
fn done(&mut self) {}
|
||||||
|
|
||||||
fn register_extension_as(&mut self) -> &'static [u16] {
|
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 {
|
fn get_prop_val(&mut self, num: usize, val: ReturnValue) -> bool {
|
||||||
match num {
|
match num {
|
||||||
0 => val.set_i32(111226),
|
0 => val.set_i32(self.test),
|
||||||
1 => val.set_i32(self.prop_i32),
|
1 => val.set_i32(self.prop_i32),
|
||||||
2 => val.set_f64(self.prop_f64),
|
2 => val.set_f64(self.prop_f64),
|
||||||
3 => val.set_bool(self.prop_bool),
|
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 {
|
fn set_prop_val(&mut self, num: usize, val: &ParamValue) -> bool {
|
||||||
match num {
|
match num {
|
||||||
|
0 => match val {
|
||||||
|
ParamValue::I32(x) => {
|
||||||
|
self.test = *x;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
1 => match val {
|
1 => match val {
|
||||||
ParamValue::I32(x) => {
|
ParamValue::I32(x) => {
|
||||||
self.prop_i32 = *x;
|
self.prop_i32 = *x;
|
||||||
@ -140,7 +145,7 @@ impl Addin for Addin1 {
|
|||||||
|
|
||||||
fn is_prop_writable(&mut self, num: usize) -> bool {
|
fn is_prop_writable(&mut self, num: usize) -> bool {
|
||||||
match num {
|
match num {
|
||||||
0 => false,
|
0 => true,
|
||||||
1 => true,
|
1 => true,
|
||||||
2 => true,
|
2 => true,
|
||||||
3 => 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]) {}
|
||||||
|
}
|
88
src/ffi.rs
88
src/ffi.rs
@ -219,7 +219,11 @@ struct TVariant {
|
|||||||
|
|
||||||
pub trait Addin {
|
pub trait Addin {
|
||||||
fn init(&mut self, interface: &'static Connection) -> bool;
|
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 done(&mut self);
|
||||||
fn register_extension_as(&mut self) -> &'static [u16];
|
fn register_extension_as(&mut self) -> &'static [u16];
|
||||||
fn get_n_props(&mut self) -> usize;
|
fn get_n_props(&mut self) -> usize;
|
||||||
@ -354,8 +358,7 @@ unsafe extern "system" fn find_prop<T: Addin>(
|
|||||||
component: &mut LanguageExtenderBase<T>,
|
component: &mut LanguageExtenderBase<T>,
|
||||||
name: *const u16,
|
name: *const u16,
|
||||||
) -> c_long {
|
) -> c_long {
|
||||||
let len = strlen(name);
|
let name = get_str(name);
|
||||||
let name = from_raw_parts(name, len);
|
|
||||||
match component.addin.find_prop(name) {
|
match component.addin.find_prop(name) {
|
||||||
Some(i) => i as c_long,
|
Some(i) => i as c_long,
|
||||||
None => -1,
|
None => -1,
|
||||||
@ -432,8 +435,7 @@ unsafe extern "system" fn find_method<T: Addin>(
|
|||||||
component: &mut LanguageExtenderBase<T>,
|
component: &mut LanguageExtenderBase<T>,
|
||||||
name: *const u16,
|
name: *const u16,
|
||||||
) -> c_long {
|
) -> c_long {
|
||||||
let len = strlen(name);
|
let name = get_str(name);
|
||||||
let name = from_raw_parts(name, len);
|
|
||||||
match component.addin.find_method(name) {
|
match component.addin.find_method(name) {
|
||||||
Some(i) => i as c_long,
|
Some(i) => i as c_long,
|
||||||
None => -1,
|
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) {
|
unsafe extern "system" fn set_locale<T: Addin>(component: &mut LocaleBase<T>, loc: *const u16) {
|
||||||
let len = strlen(loc);
|
let loc = get_str(loc);
|
||||||
let loc = from_raw_parts(loc, len);
|
|
||||||
component.addin.set_locale(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>,
|
component: &mut UserLanguageBase<T>,
|
||||||
lang: *const u16,
|
lang: *const u16,
|
||||||
) {
|
) {
|
||||||
let len = strlen(lang);
|
let lang = get_str(lang);
|
||||||
let lang = from_raw_parts(lang, len);
|
|
||||||
component.addin.set_user_interface_language_code(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>) {
|
unsafe extern "system" fn destroy<T: Addin>(component: *mut *mut ComponentBase<T>) {
|
||||||
let component = unsafe { Box::from_raw(*component) };
|
let comp = Box::from_raw(*component);
|
||||||
drop(component);
|
drop(comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[allow(dead_code)]
|
|
||||||
struct InitDoneBase<T: Addin> {
|
struct InitDoneBase<T: Addin> {
|
||||||
_vptr1: Box<InitDoneBaseVTable<T>>,
|
_vptr1: usize,
|
||||||
_vptr2: Box<LanguageExtenderBaseVTable<T>>,
|
_vptr2: usize,
|
||||||
_vptr3: Box<LocaleBaseVTable<T>>,
|
_vptr3: usize,
|
||||||
_vptr4: Box<UserLanguageBaseVTable<T>>,
|
_vptr4: usize,
|
||||||
destroy: unsafe extern "system" fn(*mut *mut ComponentBase<T>),
|
destroy: unsafe extern "system" fn(*mut *mut ComponentBase<T>),
|
||||||
memory: Option<&'static MemoryManager>,
|
memory: Option<&'static MemoryManager>,
|
||||||
addin: T,
|
addin: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
// type InitDoneBase<T> = ComponentBase<T>;
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
struct LanguageExtenderBase<T: Addin> {
|
struct LanguageExtenderBase<T: Addin> {
|
||||||
_vptr2: Box<LanguageExtenderBaseVTable<T>>,
|
_vptr2: usize,
|
||||||
_vptr3: Box<LocaleBaseVTable<T>>,
|
_vptr3: usize,
|
||||||
_vptr4: Box<UserLanguageBaseVTable<T>>,
|
_vptr4: usize,
|
||||||
destroy: unsafe extern "system" fn(*mut *mut ComponentBase<T>),
|
destroy: unsafe extern "system" fn(*mut *mut ComponentBase<T>),
|
||||||
memory: Option<&'static MemoryManager>,
|
memory: Option<&'static MemoryManager>,
|
||||||
addin: T,
|
addin: T,
|
||||||
@ -620,8 +617,8 @@ struct LanguageExtenderBase<T: Addin> {
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
struct LocaleBase<T: Addin> {
|
struct LocaleBase<T: Addin> {
|
||||||
_vptr3: Box<LocaleBaseVTable<T>>,
|
_vptr3: usize,
|
||||||
_vptr4: Box<UserLanguageBaseVTable<T>>,
|
_vptr4: usize,
|
||||||
destroy: unsafe extern "system" fn(*mut *mut ComponentBase<T>),
|
destroy: unsafe extern "system" fn(*mut *mut ComponentBase<T>),
|
||||||
memory: Option<&'static MemoryManager>,
|
memory: Option<&'static MemoryManager>,
|
||||||
addin: T,
|
addin: T,
|
||||||
@ -630,13 +627,13 @@ struct LocaleBase<T: Addin> {
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
struct UserLanguageBase<T: Addin> {
|
struct UserLanguageBase<T: Addin> {
|
||||||
_vptr4: Box<UserLanguageBaseVTable<T>>,
|
_vptr4: usize,
|
||||||
destroy: unsafe extern "system" fn(*mut *mut ComponentBase<T>),
|
destroy: unsafe extern "system" fn(*mut *mut ComponentBase<T>),
|
||||||
memory: Option<&'static MemoryManager>,
|
memory: Option<&'static MemoryManager>,
|
||||||
addin: T,
|
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 {
|
let vptr1 = Box::new(InitDoneBaseVTable {
|
||||||
dtor: 0,
|
dtor: 0,
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
@ -693,26 +690,26 @@ pub fn create_component<T: Addin>(addin: T) -> *mut c_void {
|
|||||||
addin,
|
addin,
|
||||||
});
|
});
|
||||||
|
|
||||||
let p = Box::leak(c);
|
*component = Box::into_raw(c) as *mut c_void;
|
||||||
p as *mut ComponentBase<T> 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)]
|
#[repr(C)]
|
||||||
#[allow(dead_code)]
|
|
||||||
struct ComponentWrapper {
|
struct ComponentWrapper {
|
||||||
vptr1: Box<c_void>,
|
vptr1: usize,
|
||||||
vptr2: Box<c_void>,
|
vptr2: usize,
|
||||||
vptr3: Box<c_void>,
|
vptr3: usize,
|
||||||
vptr4: Box<c_void>,
|
vptr4: usize,
|
||||||
destroy: unsafe extern "system" fn(*mut *mut c_void),
|
destroy: unsafe extern "system" fn(*mut *mut c_void),
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
let wrapper = *component as *mut ComponentWrapper;
|
||||||
let wrapper = *component as *mut ComponentWrapper;
|
let wrapper = &mut *wrapper;
|
||||||
let wrapper = &mut *wrapper;
|
(wrapper.destroy)(component);
|
||||||
(wrapper.destroy)(component);
|
*component = ptr::null_mut();
|
||||||
}
|
|
||||||
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -759,11 +756,16 @@ pub struct Connection {
|
|||||||
vptr1: &'static ConnectionVTable,
|
vptr1: &'static ConnectionVTable,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn strlen(s: *const u16) -> usize {
|
unsafe fn get_str<'a>(s: *const u16) -> &'a [u16] {
|
||||||
let mut i = 0;
|
unsafe fn strlen(s: *const u16) -> usize {
|
||||||
while unsafe { *s.add(i) } != 0 {
|
let mut i = 0;
|
||||||
|
while unsafe { *s.add(i) } != 0 {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
|
i
|
||||||
}
|
}
|
||||||
i += 1;
|
|
||||||
i
|
let len = strlen(s);
|
||||||
|
from_raw_parts(s, len)
|
||||||
}
|
}
|
||||||
|
31
src/lib.rs
31
src/lib.rs
@ -1,8 +1,9 @@
|
|||||||
mod addin1;
|
mod addin1;
|
||||||
|
mod addin2;
|
||||||
mod ffi;
|
mod ffi;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
ffi::{c_long, c_void, c_int},
|
ffi::{c_int, c_long, c_void},
|
||||||
sync::atomic::{AtomicI32, Ordering},
|
sync::atomic::{AtomicI32, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -10,36 +11,42 @@ use addin1::Addin1;
|
|||||||
use ffi::{destroy_component, AttachType};
|
use ffi::{destroy_component, AttachType};
|
||||||
use utf16_lit::utf16_null;
|
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);
|
pub static mut PLATFORM_CAPABILITIES: AtomicI32 = AtomicI32::new(-1);
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[no_mangle]
|
#[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 {
|
||||||
let addin = Addin1::new();
|
match *name as u8 {
|
||||||
unsafe {
|
b'1' => {
|
||||||
*component = create_component(addin);
|
let addin = Addin1::new();
|
||||||
|
create_component(component, addin)
|
||||||
|
}
|
||||||
|
b'2' => {
|
||||||
|
let addin = Addin2::new();
|
||||||
|
create_component(component, addin)
|
||||||
|
}
|
||||||
|
_ => 0,
|
||||||
}
|
}
|
||||||
1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn DestroyObject(component: *mut *mut c_void) -> c_long {
|
pub unsafe extern "C" fn DestroyObject(component: *mut *mut c_void) -> c_long {
|
||||||
destroy_component(component);
|
destroy_component(component)
|
||||||
0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn GetClassNames() -> *const u16 {
|
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)]
|
#[allow(non_snake_case)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn SetPlatformCapabilities(capabilities: c_int) -> c_long {
|
pub extern "C" fn SetPlatformCapabilities(capabilities: c_int) -> c_int {
|
||||||
unsafe {
|
unsafe {
|
||||||
PLATFORM_CAPABILITIES.store(capabilities, Ordering::Relaxed);
|
PLATFORM_CAPABILITIES.store(capabilities, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user