Struct java_spaghetti::Env

source ·
pub struct Env<'env> { /* private fields */ }
Expand description

FFI: Use Env instead of *const JNIEnv. This represents a per-thread Java exection environment.

A “safe” alternative to jni_sys::JNIEnv raw pointers, with the following caveats:

  1. A null env will result in undefined behavior. Java should not be invoking your native functions with a null *mut JNIEnv, however, so I don’t believe this is a problem in practice unless you’ve bindgened the C header definitions elsewhere, calling them (requiring unsafe), and passing null pointers (generally UB for JNI functions anyways, so can be seen as a caller soundness issue.)

  2. Allowing the underlying JNIEnv to be modified is undefined behavior. I don’t believe the JNI libraries modify the JNIEnv, so as long as you’re not accepting a *mut JNIEnv elsewhere, using unsafe to dereference it, and mucking with the methods on it yourself, I believe this “should” be fine.

§Example

§MainActivity.java

package com.maulingmonkey.example;

public class MainActivity extends androidx.appcompat.app.AppCompatActivity {
    @Override
    public native boolean dispatchKeyEvent(android.view.KeyEvent keyEvent);

    // ...
}

§main_activity.rs

use jni_sys::{jboolean, jobject, JNI_TRUE}; // TODO: Replace with safer equivalent
use java_spaghetti::Env;

#[no_mangle] pub extern "system"
fn Java_com_maulingmonkey_example_MainActivity_dispatchKeyEvent<'env>(
    _env:       Env<'env>,
    _this:      jobject, // TODO: Replace with safer equivalent
    _key_event: jobject  // TODO: Replace with safer equivalent
) -> jboolean {
    // ...
    JNI_TRUE
}

Implementations§

source§

impl<'env> Env<'env>

source

pub unsafe fn from_raw(ptr: *mut JNIEnv) -> Self

source

pub fn as_raw(&self) -> *mut JNIEnv

source

pub fn vm(&self) -> VM

source

pub unsafe fn new_string(self, chars: *const jchar, len: jsize) -> jstring

source

pub unsafe fn get_string_length(self, string: jstring) -> jsize

source

pub unsafe fn get_string_chars(self, string: jstring) -> *const jchar

source

pub unsafe fn release_string_chars(self, string: jstring, chars: *const jchar)

source

pub unsafe fn set_class_loader(classloader: jobject)

Set a custom class loader to use instead of JNI FindClass calls.

When calling Java methods, java-spaghetti may need to resolve class names (as strings) into jclass pointers. The JNI API provides FindClass to do it. However, it is hardcoded to use the class loader for the class that called the currently-running native method.

This works fine most of the time, except:

  • On a thread created by native code (such as with std::thread::spawn()), there is no “class that called a native method” in the call stack, since the execution already started in native code. In this case, FindClass falls back to the system class loader.
  • On Android, the system class loader can’t find classes for your application, it can only find classes from the Android frameworks.

set_class_loader allows you to set a ClassLoader instance that java-spaghetti will use to resolve class names, by calling the loadClass method, instead of doing JNI FindClass calls.

Calling this with a null classloader reverts back to using JNI FindClass.

§Safety
  • classloader must be a global reference to a java.lang.ClassLoader instance.
  • The library does not take ownership of the global reference. I.e. it will not delete it if you call set_class_loader with another class loader, or with null.
source

pub unsafe fn require_class(self, class: &str) -> jclass

source

pub unsafe fn require_method( self, class: jclass, method: &str, descriptor: &str ) -> jmethodID

source

pub unsafe fn require_static_method( self, class: jclass, method: &str, descriptor: &str ) -> jmethodID

source

pub unsafe fn require_field( self, class: jclass, field: &str, descriptor: &str ) -> jfieldID

source

pub unsafe fn require_static_field( self, class: jclass, field: &str, descriptor: &str ) -> jfieldID

source

pub unsafe fn require_class_method( self, class: &str, method: &str, descriptor: &str ) -> (jclass, jmethodID)

source

pub unsafe fn require_class_static_method( self, class: &str, method: &str, descriptor: &str ) -> (jclass, jmethodID)

source

pub unsafe fn require_class_field( self, class: &str, method: &str, descriptor: &str ) -> (jclass, jfieldID)

source

pub unsafe fn require_class_static_field( self, class: &str, method: &str, descriptor: &str ) -> (jclass, jfieldID)

source

pub unsafe fn new_object_a<R: ReferenceType, E: ThrowableType>( self, class: jclass, method: jmethodID, args: *const jvalue ) -> Result<Local<'env, R>, Local<'env, E>>

source

pub unsafe fn call_object_method_a<R: ReferenceType, E: ThrowableType>( self, this: jobject, method: jmethodID, args: *const jvalue ) -> Result<Option<Local<'env, R>>, Local<'env, E>>

source

pub unsafe fn call_boolean_method_a<E: ThrowableType>( self, this: jobject, method: jmethodID, args: *const jvalue ) -> Result<bool, Local<'env, E>>

source

pub unsafe fn call_byte_method_a<E: ThrowableType>( self, this: jobject, method: jmethodID, args: *const jvalue ) -> Result<jbyte, Local<'env, E>>

source

pub unsafe fn call_char_method_a<E: ThrowableType>( self, this: jobject, method: jmethodID, args: *const jvalue ) -> Result<jchar, Local<'env, E>>

source

pub unsafe fn call_short_method_a<E: ThrowableType>( self, this: jobject, method: jmethodID, args: *const jvalue ) -> Result<jshort, Local<'env, E>>

source

pub unsafe fn call_int_method_a<E: ThrowableType>( self, this: jobject, method: jmethodID, args: *const jvalue ) -> Result<jint, Local<'env, E>>

source

pub unsafe fn call_long_method_a<E: ThrowableType>( self, this: jobject, method: jmethodID, args: *const jvalue ) -> Result<jlong, Local<'env, E>>

source

pub unsafe fn call_float_method_a<E: ThrowableType>( self, this: jobject, method: jmethodID, args: *const jvalue ) -> Result<jfloat, Local<'env, E>>

source

pub unsafe fn call_double_method_a<E: ThrowableType>( self, this: jobject, method: jmethodID, args: *const jvalue ) -> Result<jdouble, Local<'env, E>>

source

pub unsafe fn call_void_method_a<E: ThrowableType>( self, this: jobject, method: jmethodID, args: *const jvalue ) -> Result<(), Local<'env, E>>

source

pub unsafe fn call_static_object_method_a<R: ReferenceType, E: ThrowableType>( self, class: jclass, method: jmethodID, args: *const jvalue ) -> Result<Option<Local<'env, R>>, Local<'env, E>>

source

pub unsafe fn call_static_boolean_method_a<E: ThrowableType>( self, class: jclass, method: jmethodID, args: *const jvalue ) -> Result<bool, Local<'env, E>>

source

pub unsafe fn call_static_byte_method_a<E: ThrowableType>( self, class: jclass, method: jmethodID, args: *const jvalue ) -> Result<jbyte, Local<'env, E>>

source

pub unsafe fn call_static_char_method_a<E: ThrowableType>( self, class: jclass, method: jmethodID, args: *const jvalue ) -> Result<jchar, Local<'env, E>>

source

pub unsafe fn call_static_short_method_a<E: ThrowableType>( self, class: jclass, method: jmethodID, args: *const jvalue ) -> Result<jshort, Local<'env, E>>

source

pub unsafe fn call_static_int_method_a<E: ThrowableType>( self, class: jclass, method: jmethodID, args: *const jvalue ) -> Result<jint, Local<'env, E>>

source

pub unsafe fn call_static_long_method_a<E: ThrowableType>( self, class: jclass, method: jmethodID, args: *const jvalue ) -> Result<jlong, Local<'env, E>>

source

pub unsafe fn call_static_float_method_a<E: ThrowableType>( self, class: jclass, method: jmethodID, args: *const jvalue ) -> Result<jfloat, Local<'env, E>>

source

pub unsafe fn call_static_double_method_a<E: ThrowableType>( self, class: jclass, method: jmethodID, args: *const jvalue ) -> Result<jdouble, Local<'env, E>>

source

pub unsafe fn call_static_void_method_a<E: ThrowableType>( self, class: jclass, method: jmethodID, args: *const jvalue ) -> Result<(), Local<'env, E>>

source

pub unsafe fn get_object_field<R: ReferenceType>( self, this: jobject, field: jfieldID ) -> Option<Local<'env, R>>

source

pub unsafe fn get_boolean_field(self, this: jobject, field: jfieldID) -> bool

source

pub unsafe fn get_byte_field(self, this: jobject, field: jfieldID) -> jbyte

source

pub unsafe fn get_char_field(self, this: jobject, field: jfieldID) -> jchar

source

pub unsafe fn get_short_field(self, this: jobject, field: jfieldID) -> jshort

source

pub unsafe fn get_int_field(self, this: jobject, field: jfieldID) -> jint

source

pub unsafe fn get_long_field(self, this: jobject, field: jfieldID) -> jlong

source

pub unsafe fn get_float_field(self, this: jobject, field: jfieldID) -> jfloat

source

pub unsafe fn get_double_field(self, this: jobject, field: jfieldID) -> jdouble

source

pub unsafe fn set_object_field<R: ReferenceType>( self, this: jobject, field: jfieldID, value: impl AsArg<R> )

source

pub unsafe fn set_boolean_field( self, this: jobject, field: jfieldID, value: bool )

source

pub unsafe fn set_byte_field(self, this: jobject, field: jfieldID, value: jbyte)

source

pub unsafe fn set_char_field(self, this: jobject, field: jfieldID, value: jchar)

source

pub unsafe fn set_short_field( self, this: jobject, field: jfieldID, value: jshort )

source

pub unsafe fn set_int_field(self, this: jobject, field: jfieldID, value: jint)

source

pub unsafe fn set_long_field(self, this: jobject, field: jfieldID, value: jlong)

source

pub unsafe fn set_float_field( self, this: jobject, field: jfieldID, value: jfloat )

source

pub unsafe fn set_double_field( self, this: jobject, field: jfieldID, value: jdouble )

source

pub unsafe fn get_static_object_field<R: ReferenceType>( self, class: jclass, field: jfieldID ) -> Option<Local<'env, R>>

source

pub unsafe fn get_static_boolean_field( self, class: jclass, field: jfieldID ) -> bool

source

pub unsafe fn get_static_byte_field( self, class: jclass, field: jfieldID ) -> jbyte

source

pub unsafe fn get_static_char_field( self, class: jclass, field: jfieldID ) -> jchar

source

pub unsafe fn get_static_short_field( self, class: jclass, field: jfieldID ) -> jshort

source

pub unsafe fn get_static_int_field(self, class: jclass, field: jfieldID) -> jint

source

pub unsafe fn get_static_long_field( self, class: jclass, field: jfieldID ) -> jlong

source

pub unsafe fn get_static_float_field( self, class: jclass, field: jfieldID ) -> jfloat

source

pub unsafe fn get_static_double_field( self, class: jclass, field: jfieldID ) -> jdouble

source

pub unsafe fn set_static_object_field<R: ReferenceType>( self, class: jclass, field: jfieldID, value: impl AsArg<R> )

source

pub unsafe fn set_static_boolean_field( self, class: jclass, field: jfieldID, value: bool )

source

pub unsafe fn set_static_byte_field( self, class: jclass, field: jfieldID, value: jbyte )

source

pub unsafe fn set_static_char_field( self, class: jclass, field: jfieldID, value: jchar )

source

pub unsafe fn set_static_short_field( self, class: jclass, field: jfieldID, value: jshort )

source

pub unsafe fn set_static_int_field( self, class: jclass, field: jfieldID, value: jint )

source

pub unsafe fn set_static_long_field( self, class: jclass, field: jfieldID, value: jlong )

source

pub unsafe fn set_static_float_field( self, class: jclass, field: jfieldID, value: jfloat )

source

pub unsafe fn set_static_double_field( self, class: jclass, field: jfieldID, value: jdouble )

Trait Implementations§

source§

impl<'env> Clone for Env<'env>

source§

fn clone(&self) -> Env<'env>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'env> Copy for Env<'env>

Auto Trait Implementations§

§

impl<'env> Freeze for Env<'env>

§

impl<'env> RefUnwindSafe for Env<'env>

§

impl<'env> !Send for Env<'env>

§

impl<'env> !Sync for Env<'env>

§

impl<'env> Unpin for Env<'env>

§

impl<'env> !UnwindSafe for Env<'env>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.