Skip to content

Commit 6bdee88

Browse files
committed
docs: add example for passive jni registration
1 parent f3da9aa commit 6bdee88

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,41 @@ public static long initializeMMKV(@NonNull Context ctx) {
7777
}
7878
```
7979

80+
For native libraries that use passive JNI registration (e.g. `Java_com_example_test_app_TestNativeLoader_nativeMethod`),
81+
you can call the `NativeRegistrationHelper.registerNativeMethodsForLibrary` method to register the native methods.
82+
See [TestNativeLoader.java](demo-app/src/main/java/com/example/test/app/TestNativeLoader.java) for the complete example.
83+
84+
`NativeRegistrationHelper.registerNativeMethodsForLibrary` enumerates all the exported symbols in the given ELF shared object,
85+
and find the corresponding Java methods by the naming convention and register them.
86+
However, it has higher overheads than the dynamic JNI registration (e.g. `env->RegisterNatives` in the `JNI_OnLoad` callback).
87+
88+
```java
89+
import dev.tmpfs.libcoresyscall.core.NativeAccess;
90+
import dev.tmpfs.libcoresyscall.elfloader.DlExtLibraryLoader;
91+
import dev.tmpfs.libcoresyscall.elfloader.NativeRegistrationHelper;
92+
93+
public static long load(String soname) {
94+
byte[] elfData = getElfData(soname);
95+
long handle = DlExtLibraryLoader.dlopenExtFromMemory(elfData, soname, DlExtLibraryLoader.RTLD_NOW, 0, 0);
96+
if (handle != 0) {
97+
// register native methods for the library
98+
NativeRegistrationHelper.RegistrationSummary summary =
99+
NativeRegistrationHelper.registerNativeMethodsForLibrary(handle, elfData);
100+
// do some check with the native registration result
101+
Log.d("TestNativeLoader", soname + ": registerNativeMethodsForLibrary: " + summary);
102+
long jniOnLoad = DlExtLibraryLoader.dlsym(handle, "JNI_OnLoad");
103+
if (jniOnLoad != 0) {
104+
long javaVm = NativeAccess.getJavaVM();
105+
long ret = NativeAccess.callPointerFunction(jniOnLoad, javaVm, 0);
106+
if (ret < 0) {
107+
throw new IllegalStateException("JNI_OnLoad failed: " + ret);
108+
}
109+
}
110+
}
111+
return handle;
112+
}
113+
```
114+
80115
### Make System Calls
81116

82117
Here is an example of how to make syscalls with the library. It calls the `uname` system call to get the system information.

0 commit comments

Comments
 (0)