From 4c8ea67a6fe0128a1f3280d15f34171b50854b8f Mon Sep 17 00:00:00 2001 From: Shibasis Patnaik Date: Mon, 8 May 2023 13:36:42 +0530 Subject: [PATCH] Update quickref.md Added explanation for creating a Hybrid class --- docs/quickref.md | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/docs/quickref.md b/docs/quickref.md index 5f0fab1..61c308c 100644 --- a/docs/quickref.md +++ b/docs/quickref.md @@ -16,6 +16,7 @@ - [Working with Iterables](#working-with-iterables) - [Building Collections](#building-collections) - [Transferring data with direct ByteBuffer](#transferring-data-with-direct-bytebuffer) +- [Creating a Hybrid Class](#creating-a-hybrid-class) ## JavaClass definition and method registration ```cpp #include @@ -496,3 +497,62 @@ When no base class is given, JObject will be used as the base. ``` +## Creating a Hybrid Class +A hybrid class has two classes, one Java and one C++. + +When you create an object of a hybrid class, two objects are created. + +The Java object holds the pointer to the C++ object to maintain its lifecycle. + +And calls the destructor to delete the C++ object on garbage collection. + +For checking an existing implementation, see NativeRunnable in [C++](https://github.com/facebookincubator/fbjni/blob/main/cxx/fbjni/NativeRunnable.h) and [Java](https://github.com/facebookincubator/fbjni/blob/main/java/com/facebook/jni/NativeRunnable.java) + + +### First we implement the Java class +```java +package com.example; +public class SingleArgNativeFunction { + private final HybridData mHybridData; + private SingleArgNativeFunction(HybridData hybridData) { + mHybridData = hybridData; + } + private native Object nativeInvoke(Object data); + public Object invoke(Object data) { + nativeInvoke(); + } +} +``` +Or its Kotlin equivalent (the variable name mHybridData has to be same) +```kotlin +package com.example +class SingleArgNativeFunction(val mHybridData: HybridData) { + private external fun nativeInvoke(data: Any): Any + operator fun invoke(data: Any) = nativeInvoke(data) +} +``` + +### Then we implement the corresponding C++ class +```cpp +#include +namespace jni = facebook::jni; +struct SingleArgNativeFunction: public jni::HybridClass { + using FnType = std::function; + static auto constexpr kJavaDescriptor = "Lcom/example/SingleArgNativeFunction;"; + + SingleArgNativeFunction(FnType &&consumer) : consumer(std::move(consumer)) {} + static void registerNatives() { + registerHybrid({ + makeNativeMethod("nativeInvoke", SingleArgNativeFunction::operator()) + }); + } + + jobject operator()(jobject object) { + return consumer(object); + } + + private: + FnType consumer; + }; +``` +