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