1 use crate::sys::jmethodID; 2 3 /// Wrapper around [`jmethodID`] that implements `Send` + `Sync` since method IDs 4 /// are valid across threads (not tied to a `JNIEnv`). 5 /// 6 /// There is no lifetime associated with these since they aren't garbage 7 /// collected like objects and their lifetime is not implicitly connected with 8 /// the scope in which they are queried. 9 /// 10 /// It matches C's representation of the raw pointer, so it can be used in any 11 /// of the extern function argument positions that would take a [`jmethodID`]. 12 /// 13 /// # Safety 14 /// 15 /// According to the JNI spec method IDs may be invalidated when the 16 /// corresponding class is unloaded. 17 /// 18 /// Since this constraint can't be encoded as a Rust lifetime, and to avoid the 19 /// excessive cost of having every Method ID be associated with a global 20 /// reference to the corresponding class then it is the developers 21 /// responsibility to ensure they hold some class reference for the lifetime of 22 /// cached method IDs. 23 #[repr(transparent)] 24 #[derive(Copy, Clone, Debug)] 25 pub struct JMethodID { 26 internal: jmethodID, 27 } 28 29 // Method IDs are valid across threads (not tied to a JNIEnv) 30 unsafe impl Send for JMethodID {} 31 unsafe impl Sync for JMethodID {} 32 33 impl JMethodID { 34 /// Creates a [`JMethodID`] that wraps the given `raw` [`jmethodID`] 35 /// 36 /// # Safety 37 /// 38 /// Expects a valid, non-`null` ID from_raw(raw: jmethodID) -> Self39 pub unsafe fn from_raw(raw: jmethodID) -> Self { 40 debug_assert!(!raw.is_null(), "from_raw methodID argument"); 41 Self { internal: raw } 42 } 43 44 /// Unwrap to the internal jni type. into_raw(self) -> jmethodID45 pub fn into_raw(self) -> jmethodID { 46 self.internal 47 } 48 } 49 50 impl AsRef<JMethodID> for JMethodID { as_ref(&self) -> &JMethodID51 fn as_ref(&self) -> &JMethodID { 52 self 53 } 54 } 55 56 impl AsMut<JMethodID> for JMethodID { as_mut(&mut self) -> &mut JMethodID57 fn as_mut(&mut self) -> &mut JMethodID { 58 self 59 } 60 } 61