Hello, I am trying to make my first mobile app wit...
# multiplatform
b
Hello, I am trying to make my first mobile app with the Superpowered audio SDK, which is in C++. I've found this post that links to the Skiko library as an example in how to use C++ in a multiplatform context. My problem is that Skiko is very complex, yet alone the
buildSrc
folder is huge. For instance, Skiko doesn't even have a
CMakeLists.txt
, and I don't understand how it works without it. Superpowered has an example about how to use the library with React Native, but I'm not sure about how to adapt it to Kotlin Multiplatform. (This example does have a
CMakeLists.txt
) Maybe there is a simpler example than Skiko that would allow me to run C++ code from Compose Multiplatform ?
a
Hi, here is a simple sample of native code on KMP https://github.com/antonymken/native-kmm
👍 2
thank you frog 1
basically create a C wrapper for c++ header files containing methods you wish to expose.
s
What are your target platforms? For JVM platforms (android, desktop) you'd use JNI to call into the native library. JNI is pretty complex, but there are some libraries out there that make it easier at the cost of some performance. It's easiest if the library has C bindings (or you write some C headers). For iOS (Native), you can interop with C or Objective C. So again you'll want C headers. Look into
cinterop
. If you're targeting web, I assume you'd have to compile the C++ library to Wasm and call into that, if it's possible at all.
m
For JVM you could als consider “The Foreign Function & Memory (FFM) API, introduced in JDK 22 as the preferred alternative to JNI”.
s
I think that won’t be available on Android for a while (if at all) and even if it’s introduced today, would take many years to become available on ~95% of target devices if it’s tied to SDK version (rather than a library bundled with the app)
it’s viable for desktop if we’re okay with requiring a pretty recent JDK, but whatever solution for android will probably be pretty applicable for desktop too, so prob won’t make sense to do separate bindings on desktop
well, seems somebody has ported it, so maybe Google will make it available as some sort of compat library compatible with older Android versions
m
@Sargun Vohra I fully agree with you. Having to maintain two separate bindings does not make sense. I just mentioned this option for completeness and in case someone wants to target only the desktop platform.
b
Thank you everyone for your help ! For now, I am only targeting Android and iOS, but I do appreciate also knowing about other platforms.
s
@Michael Paus totally reasonable; sorry if I came off as dismissive of that option, it wasn't my intention 😅 For my project, I'm eyeing https://github.com/jnr/jnr-ffi. Haven't tried it, unsure how well it'll work, but seems like it can make this kind of integration much easier
b
@appgen, thank you a lot for your sample repository, this is a real gold mine for me ! I've been reading through it, and two things remain unclear, maybe you (or someone here) can answer, otherwise I may try to contact the repo owner: • In
iosMain/kotlin/Greeting.ios.kt
, why is it necessary to have a
freeMemoryNative
function if the code is wrapped in a
memScoped
? Isn't the point of
memScoped
to free all the memory after leaving? • The Gradle build file uses the
cklib
plugin, but I'm not sure about how useful it is since android has
externalNativeBuild { cmake ...
and iOS has cinterops... Also,
./gradlew.bat build
works even with the cklib section and plugin commented out, but as I am on Windows, I cannot test iOS builds...
👌 1
a
@Bananasmoothii yes
memScoped
is sufficient
cklib
is not in use, it's a hangover from original sample
the code could use a little more clean up 😄 it is tested on ios and it works,
m
A cleaned up version of this code would be very useful and welcomed 🙏.
👍 1
b
Alright, thank you !
Oh, I just saw you already did the cleanup, thank you!
K 1
👌 1
a
@Bananasmoothii, since we are not using cklib, for IOS its best we build a c++ static library. (see updated code) note: cklib is no longer maintained and not best for production code.
the c++ code does not have to be part of the project, all we need are the header files and static library
f
b
@appgen wow thanks but I definitely didn't understand everything here. So now cinterop no longer needs to build the library on iOS because it is already added as a library in the def file ? Also, I never touched to xcode so I have no idea what you changed in the project.pbxproj file, but I guess I'll figure that out when I will get a Mac 😅
@François thanks but there is no java on iOS targets :/
a
cinterop will be generated from the provided headers. kotlin will be able to interact with c++ library through cinterop
👍 1
so we need jni, cinterop for kotlin to interact with c++ in the two platforms
👍 1
the c++ library is built separately. for IOS we can use a script like provided in sample for Android, gradle does the magic
if we have the static c++ library already built, we just provide it and the headers, to gradle for android and .def file for ios
note: for jni, cinterop we need c headers and not c++ headers
nothing much for xcode, one only needs to set the generated KMP framework as a target.
👍 1
b
But if cinterop builds the library (which I thought it did before), why bother building it ourselves?
(@appgen)
a
@Bananasmoothii cinterop does not compile c, c++ applications. It is a bridge between kotlin and the already built c,c++ library
b
Ah ok, but how did it work before then ? What was building the C++ part on iOS ?
(sorry @appgen I ask a lot of questions but without you, I would have been totally lost 😅)
a
before, it was using cklib to do the magic, Note that cklib is no longer maintained as such it is not best to use it.
no problem asking questions, also look for lots of articles on how to build on KMP. The information is hardly in one place. I probably put together pieces of information from 6 or more sites
b
Ah ok, got it, many thanks !
a
basically create a C wrapper for c++ header files containing methods you wish to expose.
something to consider, at least if you run into problems, is building a plain C program to call the libs and ensure that all is well before the complexities of interop come in on top