mono_rt/types/assembly.rs
1use std::ffi::{CString, c_char};
2
3use super::{MonoImage, mono_handle};
4use crate::{MonoError, MonoImageOpenStatus, Result, api};
5
6mono_handle!(MonoAssembly);
7
8impl MonoAssembly {
9 /// Registers a `MonoImage` as a fully loaded assembly in the current domain.
10 ///
11 /// `base_dir` is the directory hint Mono uses to resolve dependent assemblies. Pass `None`
12 /// to rely on the standard assembly search path (correct for most injection scenarios).
13 ///
14 /// # Errors
15 ///
16 /// Returns [`MonoError::NullByteInName`] if `base_dir` contains an interior null byte.
17 /// Returns [`MonoError::ImageOpenFailed`] if Mono rejects the image.
18 /// Returns [`MonoError::Uninitialized`] if the Mono API has not been initialized.
19 pub fn load_from_image(image: MonoImage, base_dir: Option<&str>) -> Result<Option<Self>> {
20 // dir_c must outlive dir_ptr — hoisted here so it lives for the whole function body.
21 let dir_c;
22 let dir_ptr: *const c_char = if let Some(s) = base_dir {
23 dir_c = CString::new(s).map_err(|_| MonoError::NullByteInName)?;
24 dir_c.as_ptr()
25 } else {
26 c"".as_ptr()
27 };
28
29 let mut status: i32 = 0;
30 let ptr = api()?.assembly_load_from_full(
31 image.as_ptr(),
32 dir_ptr,
33 std::ptr::addr_of_mut!(status),
34 0,
35 );
36
37 let s = MonoImageOpenStatus::from_raw(status);
38 if !s.is_ok() {
39 return Err(MonoError::ImageOpenFailed(s));
40 }
41
42 if ptr.is_null() {
43 return Err(MonoError::ImageOpenFailed(s));
44 }
45
46 Ok(MonoAssembly::from_ptr(ptr))
47 }
48
49 /// Unloads this assembly from the runtime.
50 ///
51 /// Call this during ejection after invoking the managed unload method. Using any handle
52 /// derived from this assembly after `close` is undefined behavior.
53 ///
54 /// # Errors
55 ///
56 /// Returns [`MonoError::Uninitialized`] if the Mono API has not been initialized.
57 pub fn close(self) -> Result<()> {
58 api()?.assembly_close(self.as_ptr());
59 Ok(())
60 }
61
62 /// Returns the metadata image for this assembly.
63 ///
64 /// # Errors
65 ///
66 /// Returns [`crate::MonoError::Uninitialized`] if the Mono API has not been initialized.
67 pub fn image(self) -> Result<Option<MonoImage>> {
68 let ptr = api()?.assembly_get_image(self.as_ptr());
69 Ok(MonoImage::from_ptr(ptr))
70 }
71}