wrapped_mono/
assembly.rs

1use crate::binds::MonoAssembly;
2use crate::image::Image;
3use std::ffi::CString;
4/// Safe representation of an executable file containing managed code and data about it.
5#[derive(Clone, Copy)]
6pub struct Assembly {
7    ptr: *mut crate::binds::MonoAssembly,
8}
9unsafe impl Send for Assembly{}
10impl Assembly {
11    /// Creates [`Assembly`] from a [`MonoAssembly`] pointer.
12    /// # Safety
13    /// *ptr* must be a valid [`MonoAssembly`] pointer.
14    #[must_use]
15    pub unsafe fn from_ptr(ptr: *mut MonoAssembly) -> Self {
16        Self { ptr }
17    }
18    /// Returns the internal pointer to [`MonoAssembly`] this object represents.
19    #[must_use]
20    pub fn get_ptr(&self) -> *mut MonoAssembly {
21        self.ptr
22    }
23    /// Gets the [`Image`] from this assembly(part of the assembly containing executable code)
24    #[must_use]
25    pub fn get_image(&self) -> Image {
26        unsafe { Image::from_ptr(crate::binds::mono_assembly_get_image(self.ptr)) }
27    }
28    /// Returns main assembly(first loaded assembly)
29    #[must_use]
30    pub fn get_main() -> Option<Self> {
31        let ptr = unsafe { crate::binds::mono_assembly_get_main() };
32        if ptr.is_null() {
33            None
34        } else {
35            unsafe { Some(Self::from_ptr(ptr)) }
36        }
37    }
38    /// Gets name of assembly.
39    #[must_use]
40    pub fn get_name(&self) -> String {
41        // assembly_name does not have to be freed, because it lives as long as the assembly.
42        let assembly_name_ptr = unsafe { crate::binds::mono_assembly_get_name(self.ptr) };
43        let cstr_name = unsafe {
44            CString::from_raw(
45                crate::binds::mono_assembly_name_get_name(assembly_name_ptr) as *mut i8
46            )
47        };
48        let name = cstr_name
49            .to_str()
50            .expect("Could not create String!")
51            .to_owned();
52        let _ = cstr_name.into_raw(); //release pointer
53        name
54    }
55    /// Checks if assembly *name* is loaded, and if it is returns that assembly.
56    #[must_use]
57    pub fn assembly_loaded(name: &str) -> Option<Self> {
58        let cstr = CString::new(name).expect(crate::STR2CSTR_ERR);
59        let assembly_name = unsafe { crate::binds::mono_assembly_name_new(cstr.as_ptr()) };
60        let ptr = unsafe { crate::binds::mono_assembly_loaded(assembly_name) };
61        drop(cstr);
62        unsafe { crate::binds::mono_assembly_name_free(assembly_name) };
63        if ptr.is_null() {
64            None
65        } else {
66            unsafe { Some(Self::from_ptr(ptr)) }
67        }
68    }
69    /// Releases reference to assembly. Assembly is closed when all outside references  to it are released.
70    pub fn close(self) {
71        unsafe { crate::binds::mono_assembly_close(self.ptr) };
72    }
73}