1use std::marker::PhantomData;
2use std::os::raw::c_char;
3use std::ptr::null_mut;
4use std::sync::atomic::{AtomicPtr, Ordering};
5
6use jni_sys::*;
7
8use crate::{AsArg, Local, ReferenceType, ThrowableType, VM};
9
10#[repr(transparent)]
55#[derive(Copy, Clone)]
56pub struct Env<'env> {
57 env: *mut JNIEnv,
58 pd: PhantomData<&'env mut JNIEnv>,
59}
60
61static CLASS_LOADER: AtomicPtr<_jobject> = AtomicPtr::new(null_mut());
62
63impl<'env> Env<'env> {
64 pub unsafe fn from_raw(ptr: *mut JNIEnv) -> Self {
65 Self {
66 env: ptr,
67 pd: PhantomData,
68 }
69 }
70
71 pub fn as_raw(&self) -> *mut JNIEnv {
72 self.env
73 }
74
75 pub fn vm(&self) -> VM {
76 let jni_env = self.as_raw();
77 let mut vm = null_mut();
78 let err = unsafe { ((**jni_env).v1_2.GetJavaVM)(jni_env, &mut vm) };
79 assert_eq!(err, JNI_OK);
80 assert_ne!(vm, null_mut());
81 unsafe { VM::from_raw(vm) }
82 }
83
84 pub unsafe fn new_string(self, chars: *const jchar, len: jsize) -> jstring {
87 ((**self.env).v1_2.NewString)(self.env, chars as *const _, len)
88 }
89
90 pub unsafe fn get_string_length(self, string: jstring) -> jsize {
91 ((**self.env).v1_2.GetStringLength)(self.env, string)
92 }
93
94 pub unsafe fn get_string_chars(self, string: jstring) -> *const jchar {
95 ((**self.env).v1_2.GetStringChars)(self.env, string, null_mut()) as *const _
96 }
97
98 pub unsafe fn release_string_chars(self, string: jstring, chars: *const jchar) {
99 ((**self.env).v1_2.ReleaseStringChars)(self.env, string, chars as *const _)
100 }
101
102 pub unsafe fn set_class_loader(classloader: jobject) {
129 CLASS_LOADER.store(classloader, Ordering::Relaxed);
130 }
131
132 pub unsafe fn require_class(self, class: &str) -> jclass {
133 let classloader = CLASS_LOADER.load(Ordering::Relaxed);
134 if !classloader.is_null() {
135 let chars = class
136 .trim_end_matches('\0')
137 .replace('/', ".")
138 .encode_utf16()
139 .collect::<Vec<_>>();
140 let string = unsafe { self.new_string(chars.as_ptr(), chars.len() as jsize) };
141
142 let cl_class = self.require_class_jni("java/lang/ClassLoader\0");
145 let cl_method = self.require_method(cl_class, "loadClass\0", "(Ljava/lang/String;)Ljava/lang/Class;\0");
146
147 let args = [jvalue { l: string }];
148 let result: *mut _jobject =
149 ((**self.env).v1_2.CallObjectMethodA)(self.env, classloader, cl_method, args.as_ptr());
150 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
151 if !exception.is_null() {
152 ((**self.env).v1_2.ExceptionClear)(self.env);
153 panic!("exception happened calling loadClass()");
154 } else if result.is_null() {
155 panic!("loadClass() returned null");
156 }
157
158 ((**self.env).v1_2.DeleteLocalRef)(self.env, string);
159
160 return result as jclass;
161 }
162
163 self.require_class_jni(class)
165 }
166
167 unsafe fn require_class_jni(self, class: &str) -> jclass {
168 debug_assert!(class.ends_with('\0'));
169 let class = ((**self.env).v1_2.FindClass)(self.env, class.as_ptr() as *const c_char);
170 assert!(!class.is_null());
171 class
172 }
173
174 pub unsafe fn require_method(self, class: jclass, method: &str, descriptor: &str) -> jmethodID {
175 debug_assert!(method.ends_with('\0'));
176 debug_assert!(descriptor.ends_with('\0'));
177
178 let method = ((**self.env).v1_2.GetMethodID)(
179 self.env,
180 class,
181 method.as_ptr() as *const c_char,
182 descriptor.as_ptr() as *const c_char,
183 );
184 assert!(!method.is_null());
185 method
186 }
187
188 pub unsafe fn require_static_method(self, class: jclass, method: &str, descriptor: &str) -> jmethodID {
189 debug_assert!(method.ends_with('\0'));
190 debug_assert!(descriptor.ends_with('\0'));
191
192 let method = ((**self.env).v1_2.GetStaticMethodID)(
193 self.env,
194 class,
195 method.as_ptr() as *const c_char,
196 descriptor.as_ptr() as *const c_char,
197 );
198 assert!(!method.is_null());
199 method
200 }
201
202 pub unsafe fn require_field(self, class: jclass, field: &str, descriptor: &str) -> jfieldID {
203 debug_assert!(field.ends_with('\0'));
204 debug_assert!(field.ends_with('\0'));
205
206 let field = ((**self.env).v1_2.GetFieldID)(
207 self.env,
208 class,
209 field.as_ptr() as *const c_char,
210 descriptor.as_ptr() as *const c_char,
211 );
212 assert!(!field.is_null());
213 field
214 }
215
216 pub unsafe fn require_static_field(self, class: jclass, field: &str, descriptor: &str) -> jfieldID {
217 debug_assert!(field.ends_with('\0'));
218 debug_assert!(field.ends_with('\0'));
219
220 let field = ((**self.env).v1_2.GetStaticFieldID)(
221 self.env,
222 class,
223 field.as_ptr() as *const c_char,
224 descriptor.as_ptr() as *const c_char,
225 );
226 assert!(!field.is_null());
227 field
228 }
229
230 pub unsafe fn require_class_method(self, class: &str, method: &str, descriptor: &str) -> (jclass, jmethodID) {
233 let class = self.require_class(class);
234 (class, self.require_method(class, method, descriptor))
235 }
236
237 pub unsafe fn require_class_static_method(
238 self,
239 class: &str,
240 method: &str,
241 descriptor: &str,
242 ) -> (jclass, jmethodID) {
243 let class = self.require_class(class);
244 (class, self.require_static_method(class, method, descriptor))
245 }
246
247 pub unsafe fn require_class_field(self, class: &str, method: &str, descriptor: &str) -> (jclass, jfieldID) {
248 let class = self.require_class(class);
249 (class, self.require_field(class, method, descriptor))
250 }
251
252 pub unsafe fn require_class_static_field(self, class: &str, method: &str, descriptor: &str) -> (jclass, jfieldID) {
253 let class = self.require_class(class);
254 (class, self.require_static_field(class, method, descriptor))
255 }
256
257 pub unsafe fn new_object_a<R: ReferenceType, E: ThrowableType>(
260 self,
261 class: jclass,
262 method: jmethodID,
263 args: *const jvalue,
264 ) -> Result<Local<'env, R>, Local<'env, E>> {
265 let result = ((**self.env).v1_2.NewObjectA)(self.env, class, method, args);
266 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
267 if !exception.is_null() {
268 ((**self.env).v1_2.ExceptionClear)(self.env);
269 Err(Local::from_raw(self, exception))
270 } else {
271 assert!(!result.is_null());
272 Ok(Local::from_raw(self, result))
273 }
274 }
275
276 pub unsafe fn call_object_method_a<R: ReferenceType, E: ThrowableType>(
279 self,
280 this: jobject,
281 method: jmethodID,
282 args: *const jvalue,
283 ) -> Result<Option<Local<'env, R>>, Local<'env, E>> {
284 let result = ((**self.env).v1_2.CallObjectMethodA)(self.env, this, method, args);
285 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
286 if !exception.is_null() {
287 ((**self.env).v1_2.ExceptionClear)(self.env);
288 Err(Local::from_raw(self, exception))
289 } else if result.is_null() {
290 Ok(None)
291 } else {
292 Ok(Some(Local::from_raw(self, result)))
293 }
294 }
295
296 pub unsafe fn call_boolean_method_a<E: ThrowableType>(
297 self,
298 this: jobject,
299 method: jmethodID,
300 args: *const jvalue,
301 ) -> Result<bool, Local<'env, E>> {
302 let result = ((**self.env).v1_2.CallBooleanMethodA)(self.env, this, method, args);
303 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
304 if !exception.is_null() {
305 ((**self.env).v1_2.ExceptionClear)(self.env);
306 Err(Local::from_raw(self, exception))
307 } else {
308 Ok(result != JNI_FALSE)
309 }
310 }
311
312 pub unsafe fn call_byte_method_a<E: ThrowableType>(
313 self,
314 this: jobject,
315 method: jmethodID,
316 args: *const jvalue,
317 ) -> Result<jbyte, Local<'env, E>> {
318 let result = ((**self.env).v1_2.CallByteMethodA)(self.env, this, method, args);
319 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
320 if !exception.is_null() {
321 ((**self.env).v1_2.ExceptionClear)(self.env);
322 Err(Local::from_raw(self, exception))
323 } else {
324 Ok(result)
325 }
326 }
327
328 pub unsafe fn call_char_method_a<E: ThrowableType>(
329 self,
330 this: jobject,
331 method: jmethodID,
332 args: *const jvalue,
333 ) -> Result<jchar, Local<'env, E>> {
334 let result = ((**self.env).v1_2.CallCharMethodA)(self.env, this, method, args);
335 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
336 if !exception.is_null() {
337 ((**self.env).v1_2.ExceptionClear)(self.env);
338 Err(Local::from_raw(self, exception))
339 } else {
340 Ok(result)
341 }
342 }
343
344 pub unsafe fn call_short_method_a<E: ThrowableType>(
345 self,
346 this: jobject,
347 method: jmethodID,
348 args: *const jvalue,
349 ) -> Result<jshort, Local<'env, E>> {
350 let result = ((**self.env).v1_2.CallShortMethodA)(self.env, this, method, args);
351 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
352 if !exception.is_null() {
353 ((**self.env).v1_2.ExceptionClear)(self.env);
354 Err(Local::from_raw(self, exception))
355 } else {
356 Ok(result)
357 }
358 }
359
360 pub unsafe fn call_int_method_a<E: ThrowableType>(
361 self,
362 this: jobject,
363 method: jmethodID,
364 args: *const jvalue,
365 ) -> Result<jint, Local<'env, E>> {
366 let result = ((**self.env).v1_2.CallIntMethodA)(self.env, this, method, args);
367 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
368 if !exception.is_null() {
369 ((**self.env).v1_2.ExceptionClear)(self.env);
370 Err(Local::from_raw(self, exception))
371 } else {
372 Ok(result)
373 }
374 }
375
376 pub unsafe fn call_long_method_a<E: ThrowableType>(
377 self,
378 this: jobject,
379 method: jmethodID,
380 args: *const jvalue,
381 ) -> Result<jlong, Local<'env, E>> {
382 let result = ((**self.env).v1_2.CallLongMethodA)(self.env, this, method, args);
383 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
384 if !exception.is_null() {
385 ((**self.env).v1_2.ExceptionClear)(self.env);
386 Err(Local::from_raw(self, exception))
387 } else {
388 Ok(result)
389 }
390 }
391
392 pub unsafe fn call_float_method_a<E: ThrowableType>(
393 self,
394 this: jobject,
395 method: jmethodID,
396 args: *const jvalue,
397 ) -> Result<jfloat, Local<'env, E>> {
398 let result = ((**self.env).v1_2.CallFloatMethodA)(self.env, this, method, args);
399 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
400 if !exception.is_null() {
401 ((**self.env).v1_2.ExceptionClear)(self.env);
402 Err(Local::from_raw(self, exception))
403 } else {
404 Ok(result)
405 }
406 }
407
408 pub unsafe fn call_double_method_a<E: ThrowableType>(
409 self,
410 this: jobject,
411 method: jmethodID,
412 args: *const jvalue,
413 ) -> Result<jdouble, Local<'env, E>> {
414 let result = ((**self.env).v1_2.CallDoubleMethodA)(self.env, this, method, args);
415 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
416 if !exception.is_null() {
417 ((**self.env).v1_2.ExceptionClear)(self.env);
418 Err(Local::from_raw(self, exception))
419 } else {
420 Ok(result)
421 }
422 }
423
424 pub unsafe fn call_void_method_a<E: ThrowableType>(
425 self,
426 this: jobject,
427 method: jmethodID,
428 args: *const jvalue,
429 ) -> Result<(), Local<'env, E>> {
430 ((**self.env).v1_2.CallVoidMethodA)(self.env, this, method, args);
431 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
432 if !exception.is_null() {
433 ((**self.env).v1_2.ExceptionClear)(self.env);
434 Err(Local::from_raw(self, exception))
435 } else {
436 Ok(())
437 }
438 }
439
440 pub unsafe fn call_static_object_method_a<R: ReferenceType, E: ThrowableType>(
443 self,
444 class: jclass,
445 method: jmethodID,
446 args: *const jvalue,
447 ) -> Result<Option<Local<'env, R>>, Local<'env, E>> {
448 let result = ((**self.env).v1_2.CallStaticObjectMethodA)(self.env, class, method, args);
449 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
450 if !exception.is_null() {
451 ((**self.env).v1_2.ExceptionClear)(self.env);
452 Err(Local::from_raw(self, exception))
453 } else if result.is_null() {
454 Ok(None)
455 } else {
456 Ok(Some(Local::from_raw(self, result)))
457 }
458 }
459
460 pub unsafe fn call_static_boolean_method_a<E: ThrowableType>(
461 self,
462 class: jclass,
463 method: jmethodID,
464 args: *const jvalue,
465 ) -> Result<bool, Local<'env, E>> {
466 let result = ((**self.env).v1_2.CallStaticBooleanMethodA)(self.env, class, method, args);
467 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
468 if !exception.is_null() {
469 ((**self.env).v1_2.ExceptionClear)(self.env);
470 Err(Local::from_raw(self, exception))
471 } else {
472 Ok(result != JNI_FALSE)
473 }
474 }
475
476 pub unsafe fn call_static_byte_method_a<E: ThrowableType>(
477 self,
478 class: jclass,
479 method: jmethodID,
480 args: *const jvalue,
481 ) -> Result<jbyte, Local<'env, E>> {
482 let result = ((**self.env).v1_2.CallStaticByteMethodA)(self.env, class, method, args);
483 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
484 if !exception.is_null() {
485 ((**self.env).v1_2.ExceptionClear)(self.env);
486 Err(Local::from_raw(self, exception))
487 } else {
488 Ok(result)
489 }
490 }
491
492 pub unsafe fn call_static_char_method_a<E: ThrowableType>(
493 self,
494 class: jclass,
495 method: jmethodID,
496 args: *const jvalue,
497 ) -> Result<jchar, Local<'env, E>> {
498 let result = ((**self.env).v1_2.CallStaticCharMethodA)(self.env, class, method, args);
499 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
500 if !exception.is_null() {
501 ((**self.env).v1_2.ExceptionClear)(self.env);
502 Err(Local::from_raw(self, exception))
503 } else {
504 Ok(result)
505 }
506 }
507
508 pub unsafe fn call_static_short_method_a<E: ThrowableType>(
509 self,
510 class: jclass,
511 method: jmethodID,
512 args: *const jvalue,
513 ) -> Result<jshort, Local<'env, E>> {
514 let result = ((**self.env).v1_2.CallStaticShortMethodA)(self.env, class, method, args);
515 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
516 if !exception.is_null() {
517 ((**self.env).v1_2.ExceptionClear)(self.env);
518 Err(Local::from_raw(self, exception))
519 } else {
520 Ok(result)
521 }
522 }
523
524 pub unsafe fn call_static_int_method_a<E: ThrowableType>(
525 self,
526 class: jclass,
527 method: jmethodID,
528 args: *const jvalue,
529 ) -> Result<jint, Local<'env, E>> {
530 let result = ((**self.env).v1_2.CallStaticIntMethodA)(self.env, class, method, args);
531 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
532 if !exception.is_null() {
533 ((**self.env).v1_2.ExceptionClear)(self.env);
534 Err(Local::from_raw(self, exception))
535 } else {
536 Ok(result)
537 }
538 }
539
540 pub unsafe fn call_static_long_method_a<E: ThrowableType>(
541 self,
542 class: jclass,
543 method: jmethodID,
544 args: *const jvalue,
545 ) -> Result<jlong, Local<'env, E>> {
546 let result = ((**self.env).v1_2.CallStaticLongMethodA)(self.env, class, method, args);
547 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
548 if !exception.is_null() {
549 ((**self.env).v1_2.ExceptionClear)(self.env);
550 Err(Local::from_raw(self, exception))
551 } else {
552 Ok(result)
553 }
554 }
555
556 pub unsafe fn call_static_float_method_a<E: ThrowableType>(
557 self,
558 class: jclass,
559 method: jmethodID,
560 args: *const jvalue,
561 ) -> Result<jfloat, Local<'env, E>> {
562 let result = ((**self.env).v1_2.CallStaticFloatMethodA)(self.env, class, method, args);
563 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
564 if !exception.is_null() {
565 ((**self.env).v1_2.ExceptionClear)(self.env);
566 Err(Local::from_raw(self, exception))
567 } else {
568 Ok(result)
569 }
570 }
571
572 pub unsafe fn call_static_double_method_a<E: ThrowableType>(
573 self,
574 class: jclass,
575 method: jmethodID,
576 args: *const jvalue,
577 ) -> Result<jdouble, Local<'env, E>> {
578 let result = ((**self.env).v1_2.CallStaticDoubleMethodA)(self.env, class, method, args);
579 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
580 if !exception.is_null() {
581 ((**self.env).v1_2.ExceptionClear)(self.env);
582 Err(Local::from_raw(self, exception))
583 } else {
584 Ok(result)
585 }
586 }
587
588 pub unsafe fn call_static_void_method_a<E: ThrowableType>(
589 self,
590 class: jclass,
591 method: jmethodID,
592 args: *const jvalue,
593 ) -> Result<(), Local<'env, E>> {
594 ((**self.env).v1_2.CallStaticVoidMethodA)(self.env, class, method, args);
595 let exception = ((**self.env).v1_2.ExceptionOccurred)(self.env);
596 if !exception.is_null() {
597 ((**self.env).v1_2.ExceptionClear)(self.env);
598 Err(Local::from_raw(self, exception))
599 } else {
600 Ok(())
601 }
602 }
603
604 pub unsafe fn get_object_field<R: ReferenceType>(self, this: jobject, field: jfieldID) -> Option<Local<'env, R>> {
607 let result = ((**self.env).v1_2.GetObjectField)(self.env, this, field);
608 if result.is_null() {
609 None
610 } else {
611 Some(Local::from_raw(self, result))
612 }
613 }
614
615 pub unsafe fn get_boolean_field(self, this: jobject, field: jfieldID) -> bool {
616 let result = ((**self.env).v1_2.GetBooleanField)(self.env, this, field);
617 result != JNI_FALSE
618 }
619
620 pub unsafe fn get_byte_field(self, this: jobject, field: jfieldID) -> jbyte {
621 ((**self.env).v1_2.GetByteField)(self.env, this, field)
622 }
623
624 pub unsafe fn get_char_field(self, this: jobject, field: jfieldID) -> jchar {
625 ((**self.env).v1_2.GetCharField)(self.env, this, field)
626 }
627
628 pub unsafe fn get_short_field(self, this: jobject, field: jfieldID) -> jshort {
629 ((**self.env).v1_2.GetShortField)(self.env, this, field)
630 }
631
632 pub unsafe fn get_int_field(self, this: jobject, field: jfieldID) -> jint {
633 ((**self.env).v1_2.GetIntField)(self.env, this, field)
634 }
635
636 pub unsafe fn get_long_field(self, this: jobject, field: jfieldID) -> jlong {
637 ((**self.env).v1_2.GetLongField)(self.env, this, field)
638 }
639
640 pub unsafe fn get_float_field(self, this: jobject, field: jfieldID) -> jfloat {
641 ((**self.env).v1_2.GetFloatField)(self.env, this, field)
642 }
643
644 pub unsafe fn get_double_field(self, this: jobject, field: jfieldID) -> jdouble {
645 ((**self.env).v1_2.GetDoubleField)(self.env, this, field)
646 }
647
648 pub unsafe fn set_object_field<R: ReferenceType>(self, this: jobject, field: jfieldID, value: impl AsArg<R>) {
649 ((**self.env).v1_2.SetObjectField)(self.env, this, field, value.as_arg());
650 }
651
652 pub unsafe fn set_boolean_field(self, this: jobject, field: jfieldID, value: bool) {
653 ((**self.env).v1_2.SetBooleanField)(self.env, this, field, if value { JNI_TRUE } else { JNI_FALSE });
654 }
655
656 pub unsafe fn set_byte_field(self, this: jobject, field: jfieldID, value: jbyte) {
657 ((**self.env).v1_2.SetByteField)(self.env, this, field, value);
658 }
659
660 pub unsafe fn set_char_field(self, this: jobject, field: jfieldID, value: jchar) {
661 ((**self.env).v1_2.SetCharField)(self.env, this, field, value);
662 }
663
664 pub unsafe fn set_short_field(self, this: jobject, field: jfieldID, value: jshort) {
665 ((**self.env).v1_2.SetShortField)(self.env, this, field, value);
666 }
667
668 pub unsafe fn set_int_field(self, this: jobject, field: jfieldID, value: jint) {
669 ((**self.env).v1_2.SetIntField)(self.env, this, field, value);
670 }
671
672 pub unsafe fn set_long_field(self, this: jobject, field: jfieldID, value: jlong) {
673 ((**self.env).v1_2.SetLongField)(self.env, this, field, value);
674 }
675
676 pub unsafe fn set_float_field(self, this: jobject, field: jfieldID, value: jfloat) {
677 ((**self.env).v1_2.SetFloatField)(self.env, this, field, value);
678 }
679
680 pub unsafe fn set_double_field(self, this: jobject, field: jfieldID, value: jdouble) {
681 ((**self.env).v1_2.SetDoubleField)(self.env, this, field, value);
682 }
683
684 pub unsafe fn get_static_object_field<R: ReferenceType>(
687 self,
688 class: jclass,
689 field: jfieldID,
690 ) -> Option<Local<'env, R>> {
691 let result = ((**self.env).v1_2.GetStaticObjectField)(self.env, class, field);
692 if result.is_null() {
693 None
694 } else {
695 Some(Local::from_raw(self, result))
696 }
697 }
698
699 pub unsafe fn get_static_boolean_field(self, class: jclass, field: jfieldID) -> bool {
700 let result = ((**self.env).v1_2.GetStaticBooleanField)(self.env, class, field);
701 result != JNI_FALSE
702 }
703
704 pub unsafe fn get_static_byte_field(self, class: jclass, field: jfieldID) -> jbyte {
705 ((**self.env).v1_2.GetStaticByteField)(self.env, class, field)
706 }
707
708 pub unsafe fn get_static_char_field(self, class: jclass, field: jfieldID) -> jchar {
709 ((**self.env).v1_2.GetStaticCharField)(self.env, class, field)
710 }
711
712 pub unsafe fn get_static_short_field(self, class: jclass, field: jfieldID) -> jshort {
713 ((**self.env).v1_2.GetStaticShortField)(self.env, class, field)
714 }
715
716 pub unsafe fn get_static_int_field(self, class: jclass, field: jfieldID) -> jint {
717 ((**self.env).v1_2.GetStaticIntField)(self.env, class, field)
718 }
719
720 pub unsafe fn get_static_long_field(self, class: jclass, field: jfieldID) -> jlong {
721 ((**self.env).v1_2.GetStaticLongField)(self.env, class, field)
722 }
723
724 pub unsafe fn get_static_float_field(self, class: jclass, field: jfieldID) -> jfloat {
725 ((**self.env).v1_2.GetStaticFloatField)(self.env, class, field)
726 }
727
728 pub unsafe fn get_static_double_field(self, class: jclass, field: jfieldID) -> jdouble {
729 ((**self.env).v1_2.GetStaticDoubleField)(self.env, class, field)
730 }
731
732 pub unsafe fn set_static_object_field<R: ReferenceType>(
733 self,
734 class: jclass,
735 field: jfieldID,
736 value: impl AsArg<R>,
737 ) {
738 ((**self.env).v1_2.SetStaticObjectField)(self.env, class, field, value.as_arg());
739 }
740
741 pub unsafe fn set_static_boolean_field(self, class: jclass, field: jfieldID, value: bool) {
742 ((**self.env).v1_2.SetStaticBooleanField)(self.env, class, field, if value { JNI_TRUE } else { JNI_FALSE });
743 }
744
745 pub unsafe fn set_static_byte_field(self, class: jclass, field: jfieldID, value: jbyte) {
746 ((**self.env).v1_2.SetStaticByteField)(self.env, class, field, value);
747 }
748
749 pub unsafe fn set_static_char_field(self, class: jclass, field: jfieldID, value: jchar) {
750 ((**self.env).v1_2.SetStaticCharField)(self.env, class, field, value);
751 }
752
753 pub unsafe fn set_static_short_field(self, class: jclass, field: jfieldID, value: jshort) {
754 ((**self.env).v1_2.SetStaticShortField)(self.env, class, field, value);
755 }
756
757 pub unsafe fn set_static_int_field(self, class: jclass, field: jfieldID, value: jint) {
758 ((**self.env).v1_2.SetStaticIntField)(self.env, class, field, value);
759 }
760
761 pub unsafe fn set_static_long_field(self, class: jclass, field: jfieldID, value: jlong) {
762 ((**self.env).v1_2.SetStaticLongField)(self.env, class, field, value);
763 }
764
765 pub unsafe fn set_static_float_field(self, class: jclass, field: jfieldID, value: jfloat) {
766 ((**self.env).v1_2.SetStaticFloatField)(self.env, class, field, value);
767 }
768
769 pub unsafe fn set_static_double_field(self, class: jclass, field: jfieldID, value: jdouble) {
770 ((**self.env).v1_2.SetStaticDoubleField)(self.env, class, field, value);
771 }
772}