From 7568515bcc5148b61ee3091c6f5146e281734044 Mon Sep 17 00:00:00 2001 From: Jamieson Pryor Date: Mon, 13 Nov 2023 13:57:07 -0800 Subject: [PATCH] Add documentation for NewRef. See https://github.com/google/jni-bind/issues/207. Also, fix minor typos to be able to finally cut a new release. PiperOrigin-RevId: 582074658 --- README.md | 10 +++++++--- implementation/jni_helper/jni_helper.h | 2 +- implementation/jni_type.h | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index bd5e9fb4..30e99150 100644 --- a/README.md +++ b/README.md @@ -166,13 +166,13 @@ jni::Class definitions are static (the class names of any Java object is known i Local and global objects manage lifetimes of underlying `jobjects` using the normal RAII mechanism of C++. **`jni::LocalObject` always fall off scope at the conclusion of the surrounding JNI call and are valid only to a single thread, however `jni::GlobalObject` may be held indefinitely and are thread safe**. -`jni::LocalObject` is built by either wrapping constructing it from a `jobject` passed to native JNI from Java, or constructing a new object from native (see [Constructors](constructors)). +`jni::LocalObject` is built by either wrapping a `jobject` passed to native JNI from Java, or constructing a new object from native (see [Constructors](constructors)). -When `jni::LocalObject` or `jni::GlobalObject` falls off scope, it will unpin the underlying `jobject`, making it available for garbage collection by the JVM. If you want to to prevent this call `Release()`. This is useful to return a `jobject` back from native, or to simply pass to another native component that isn't JNI Bind aware. Calling methods for a released object is undefined. +When `jni::LocalObject` or `jni::GlobalObject` falls off scope, it will unpin the underlying `jobject`, making it available for garbage collection by the JVM. If you want to to prevent this, call `Release()`. This is useful to return a `jobject` back from native, or to simply pass to another native component that isn't JNI Bind aware. Calling methods for a released object is undefined. When possible try to avoid using raw `jobject`. Managing lifetimes with regular JNI is difficult, e.g. `jobject` can mean either local or global object (the former will be automatically unpinned at the end of the JNI call, but the latter won't and must be deleted _exactly_ once). -Because jobject does not uniquely identify its underlying storage, it is presumed to always be local. If you want to build a global, you must use either `jni::PromoteToGlobal` or `jni::AdoptGlobal`. e.g. +Because `jobject` does not uniquely identify its underlying storage, it is presumed to always be local. If you want to build a global, you must use either `jni::PromoteToGlobal` or `jni::AdoptGlobal`. e.g. ```cpp jobject obj1, obj2, obj3; @@ -181,6 +181,10 @@ jni::LocalObject local_obj {obj1}; // Fine, given local semantics. jni::GlobalObject global_obj_1 {PromoteToGlobal{}, obj2}; // obj2 will be promoted. jni::GlobalObject global_obj_2 {AdoptGlobal{}, obj3}; // obj3 will *not* be promoted. ``` + When using a jobject you may add `NewRef{}` which creates a new local reference, or `AdoptLocal{}` which takes full ownership. + +*Because JNI objects passed to native should never be deleted, `NewRef` is used by default (so that `LocalObject` may always call delete). A non-deleting `FastLocal` that does not delete may be added in the future. In general you shouldn't need to worry about this.* + [Sample C++](javatests/com/jnibind/test/context_test_jni.cc), [Sample Java](javatests/com/jnibind/test/ContextTest.java) diff --git a/implementation/jni_helper/jni_helper.h b/implementation/jni_helper/jni_helper.h index a2e71072..49cb7dd3 100644 --- a/implementation/jni_helper/jni_helper.h +++ b/implementation/jni_helper/jni_helper.h @@ -28,7 +28,7 @@ namespace jni { class JniHelper { public: // Finds a class with "name". Note, the classloader used is whatever is - // present on the stack when this is called. No cacheing is performed, + // present on the stack when this is called. No caching is performed, // returned `jclass` is a local. static jclass FindClass(const char* name); diff --git a/implementation/jni_type.h b/implementation/jni_type.h index a3a764cb..42f9f3f1 100644 --- a/implementation/jni_type.h +++ b/implementation/jni_type.h @@ -100,7 +100,7 @@ struct JniT { static constexpr ClassT stripped_class_v{FullArrayStripV(GetClass())}; //////////////////////////////////////////////////////////////////////////// - // Minimal Spanning type (allows perfect cacheing for fully specified jvm). + // Minimal Spanning type (allows perfect caching for fully specified jvm). //////////////////////////////////////////////////////////////////////////// // kNoIdx for default loader, then provided idx, then calculated idx.