feat(codegen): native Kotlin/JNI generator + Android example over the C ABI#60
Draft
Ivansete-status wants to merge 3 commits into
Draft
feat(codegen): native Kotlin/JNI generator + Android example over the C ABI#60Ivansete-status wants to merge 3 commits into
Ivansete-status wants to merge 3 commits into
Conversation
Ivansete-status
force-pushed
the
ffi-native-typed-returns
branch
from
May 31, 2026 14:38
9c15a8e to
1060340
Compare
Ivansete-status
force-pushed
the
android-example
branch
from
May 31, 2026 14:39
2b00b18 to
60a7b88
Compare
An Android library module wrapping the timer library's native ABI behind an idiomatic Kotlin `TimerNode` class via a JNI shim. `build-libs.sh` cross-compiles two native libraries per ABI (arm64-v8a + x86_64) into src/main/jniLibs/: libmy_timer.so (the Nim library) and libmy_timer_jni.so (the JNI bridge, which NEEDs the former). The shim turns each Kotlin `external fun` into a blocking call and reads the typed EchoResponse struct out of the result callback. Gradle packages everything under jniLibs/ automatically; an instrumented test covers create/version/echo on a device/emulator. Native build validated for both ABIs (correct aarch64/x86_64 ELF, JNI symbols exported, libmy_timer.so linked). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ivansete-status
force-pushed
the
ffi-native-typed-returns
branch
from
May 31, 2026 16:38
1060340 to
c000a84
Compare
Ivansete-status
force-pushed
the
android-example
branch
from
May 31, 2026 16:38
60a7b88 to
c51f313
Compare
Ivansete-status
marked this pull request as draft
June 1, 2026 07:34
Adds ffi/codegen/kotlin.nim, wired into the targetLang dispatch and exposed as the `genbindings_kotlin` nimble task. From the same metadata it emits both artifacts an Android consumer needs over the native (zero-serialization) C ABI from c.nim: an idiomatic Kotlin AutoCloseable wrapper and the JNI shim that bridges it. Callback-shape selection is per proc (ack / string / struct), and the JNI shim blocks on a condvar until the FFI-thread callback fires so the Kotlin side stays synchronous. An all-string struct return crosses as a String[] that the wrapper repacks into a data class — matching the validated example. Procs needing seq/Option params, multiple struct params, or a non-string struct return are skipped with a logged notice so the generated code always compiles. That marshaling, events, and async are the next increments. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…pper Regenerates the wrapper (MyTimerNode.kt) and JNI shim (my_timer_jni.c) via `nimble genbindings_kotlin`, removing the hand-written sources, and points the instrumented test at the derived MyTimerNode class. Validated by cross-compiling both ABIs with the NDK: arm64-v8a + x86_64 build clean, the four Java_org_logos_mytimer_MyTimerNode_* symbols are exported, and libmy_timer_jni.so correctly NEEDS libmy_timer.so. (The Kotlin/Gradle layer still runs on a device/emulator.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Collaborator
Author
|
Expanded scope: this PR now also adds the Kotlin/JNI generator that produces the wrapper, not just the hand-written example (mirrors what #59 did for Swift).
Validated by cross-compiling both ABIs with the NDK: arm64-v8a + x86_64 build clean, the four 🤖 Generated with Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds an Android example consuming the timer library's native (zero-
serialization) C ABI from Kotlin via JNI. Based on the native-FFI stack (#58) so
it can use typed struct returns.
What
examples/timer/android/— an Android library module with an idiomatic KotlinTimerNodeclass.jni/my_timer_jni.c— a JNI shim that turns each Kotlinexternal funinto ablocking call into the native ABI and reads the typed
EchoResponsestruct outof the result callback.
build-libs.shcross-compiles, per ABI (arm64-v8a + x86_64), bothlibmy_timer.so(the Nim library) andlibmy_timer_jni.so(the bridge) intosrc/main/jniLibs/, which Gradle packages automatically. An instrumented testcovers create / version / echo.
Validation
Native build verified for both ABIs: correct aarch64/x86_64 ELF, the 4
Java_org_logos_mytimer_*symbols exported, andlibmy_timer_jni.socorrectlyNEEDSlibmy_timer.so. (Kotlin/Gradle layer runs on a device/emulator.)🤖 Generated with Claude Code