Is there a `KaMPKit` prototype project that uses l...
# multiplatform
a
Is there a
KaMPKit
prototype project that uses libcurl (or any simple C/C++ library) to show case talking to a native library from KMM project.
l
I stumbled across this repo when looking for how to combine cinterop & JNI for KMM, though I'm not certain whether it's the same thing you're asking about or not.
k
It depends on how you want to include the code. Also, no C++ for native. Just FYI. Anyway, I gave a talk on this: https://www.droidcon.com/2022/06/28/sdk-design-and-publishing-for-kotlin-multiplatform-mobile/. The title on the page is wrong, but the video is correct. In summary, You can use cocoapods to pull in a dependency (you don't need to use Cocoapods the whole way through, just to get the dep and run cinterop). If not that, you need to find out where you're getting the C source, where you're storing it, then config cinterop. There are various samples of cinterop, but it's one of those things that's just complicated enough that everybody runs into trouble. Most KMP devs aren't generally doing C work, so the basics of building binaries and linking aren't understood. It would be a good idea to work through the JB docs on cinterop, get a better understanding of it, then watch the video.
For libcurl specifically, if that library is available for iOS devices, then it would be similar to sqlite. Get the header for llbcurl, put it in your source, then point cinterop at it. Use linker flags to tell the Kotlin and/or Xcode compiler to link to the system libcurl. If libcurl is not available to iOS apps, then you'll also need to build and package the libcurl binary. The talk goes into that some. For that we have https://github.com/touchlab/cklib, but I very explicitly do not support that. Most of the questions are from devs unfamiliar with C builds and linking, so it winds up being a lot of slack chats that should really be reading the cinterop docs and learning standard and Apple C/LLVM builds instead.
Zipline uses cklib: https://github.com/cashapp/zipline/blob/trunk/zipline/build.gradle.kts#L19. It's a good public example that may be similar to your case.
For JNI/C++, I rarely touch it. Should be plenty of docs online. Bridging the two in KMP will require writing the common API manually. There are no automated tools that I'm aware of for that.
a
Yeah I checked zipline… I was more of looking for a fully working sample depending on KaMPKit
k
Well, one of the JetBrains' samples uses libcurl to explain cinterop. https://kotlinlang.org/docs/native-app-with-c-and-libcurl.html#write-the-application-code
a
Yeah I went thought it completely but not calling from iosApp
I might not looking in the right docs, but I scanned almost everything and no official docs addressing this topic
I reached the state of having platform built static .a libs for both android and iOS but nothing addresses using that at all in the official Kotlin native/multiplatform documentations
k
platform built static .a libs for both android and iOS
.a libs of libcurl or your Kotlin code? Might be easier to comment if you have a public repo to look at.
a
My built `.`an archives just includes a
printHelloWorld()
C function. The simplest possible ever example. Nothing related to libcurl, I was just trying to use it as a reference since nothing simpler than that that might be related. My problem is creating a project with shared code calling the printHelloWorld() function from both Android/iOS.
k
I'd start with one platform. I'm much more familiar with Kotlin/iOS and cinterop than JNI, but there's much more info online about JNI. You'll need to implement JNI for Android and cinterop for iOS first before getting that into shared code. So, in your KMP project, in the Android source (
androidMain
Kotlin code), configure JNI and (I would assume) the NDK to build your
printHelloWorld()
code. Once your Android/NDK code is working correctly, you should be able to call
printHelloWorld()
from Android-specific Kotlin code (in
androidMain
). To be clear, none of that is "KMP". You would code that the same if you had a strictly Android project. When that's working, you'll need to config cinterop on iOS. cinterop will need the
.h
file for
printHelloWorld()
. That will generate the Kotlin definitions with which you can call the function from
iosMain
. As in the video, you also need to figure out how to package that compiled binary. When both android and iOS are working, then you can write
commonMain
code that delegates to each platform's implementation. I'm guessing that didn't clear things up too much. There's a lot to figure out in there. The big-picture thing to understand is that native C integrations require implementations on both Android and iOS separately. That means you need to set up the JNI on Android, the cinterop on iOS. The actual "shared code" is manually written in
commonMain
and delegates to each platform for implementation. There's no auto-gen for code that allows KMP to talk to C across platforms. People have discussed it, but it wouldn't be trivial to build, to put it mildly.
a
Thanks @kpgalligan that's been helpful in verifying like %80 of the findings from my scattered research. The sequence of constructing things makes great sense now, however I thought there's always an easier way. I'll starting creating the small building blocks in the same order you stated and see how it guys. Many thanks!!
k
Good luck!