1use std::{
2 ffi::{c_void, CStr, CString},
3 ptr::null_mut,
4 sync::Arc,
5};
6
7use crate::{
8 assembly::Assembly,
9 bindings::{
10 mono_class_get_field_from_name, mono_class_get_name, mono_method_desc_new,
11 mono_method_desc_search_in_class, mono_runtime_invoke, MonoObject,
12 },
13 class::Class,
14 domain::Domain,
15 field::ObjectField,
16 image::Image,
17 method::{Arguments, ObjectMethod},
18 void::AsRawVoid,
19 MonoResult,
20};
21
22#[derive(Clone, Debug)]
23pub struct Object {
24 pub mono_ptr: *mut MonoObject,
25 pub assembly: Arc<Assembly>,
26 pub class: Arc<Class>,
27 pub domain: Arc<Domain>,
28 pub image: Arc<Image>,
29}
30
31impl Object {
32 pub fn construct(&self, args: Option<Arguments>) -> MonoResult<()> {
33 unsafe {
34 mono_runtime_invoke(
35 self.get_method_by_name(".ctor")?.mono_ptr,
36 self.mono_ptr as *mut c_void,
37 args.as_raw_void() as *mut *mut c_void,
38 null_mut(),
39 )
40 };
41 Ok(())
42 }
43
44 pub fn get_class_name(&self) -> String {
45 unsafe {
46 CStr::from_ptr(mono_class_get_name(self.class.mono_ptr))
47 .to_string_lossy()
48 .to_string()
49 }
50 }
51
52 pub fn get_method_by_name<T: AsRef<str>>(&self, name: T) -> MonoResult<ObjectMethod> {
53 let class_name = self.get_class_name();
54 let method_name = CString::new(format!("{}:{}()", class_name, name.as_ref()))?;
55 let method_desc = unsafe { mono_method_desc_new(method_name.as_ptr(), 0) };
56 let mono_ptr = unsafe { mono_method_desc_search_in_class(method_desc, self.class.mono_ptr) };
57
58 if mono_ptr.is_null() {
59 return Err("MonoMethod Null Error!".into());
60 }
61
62 Ok(ObjectMethod {
63 mono_ptr,
64 assembly: self.assembly.clone(),
65 class: self.class.clone(),
66 domain: self.domain.clone(),
67 image: self.image.clone(),
68 object: Arc::new(self.clone()),
69 })
70 }
71
72 pub fn get_field_by_name<T: AsRef<str>>(&self, name: T) -> MonoResult<ObjectField> {
73 let field_name = CString::new(name.as_ref())?;
74 let mono_ptr =
75 unsafe { mono_class_get_field_from_name(self.class.mono_ptr, field_name.as_ptr()) };
76
77 if mono_ptr.is_null() {
78 return Err("MonoField Null Error!".into());
79 }
80
81 Ok(ObjectField {
82 mono_ptr,
83 assembly: self.assembly.clone(),
84 class: self.class.clone(),
85 domain: self.domain.clone(),
86 image: self.image.clone(),
87 object: Arc::new(self.clone()),
88 })
89 }
90}
91
92impl AsRawVoid for Object {
93 fn as_raw_void(self) -> *mut c_void {
94 self.mono_ptr as *mut c_void
95 }
96}