Android Studio C++ NDK library example - android

I would like to download some working example of Android Studio NDK project with C or C++ which will be compiled to .so library (or APK from which I can extract .so).
I have tried ndkbuild with Android.mk build and also CMake with CMakeLists.txt, official and unofficial tutorials on Windows...
If I try them on android from same app (java), it is working but I want to use NDK in Unity3D on android and I keep getting DllNotFoundException.
I uploaded my Android and Unity projects to github.

First of all, here is a sample Android Project plugin you are looking for.
It's very important to know how to do this yourself.
This used to be hard to do before but the latest Android Studio made it easier to now use C/C++ or generate .so library easily. Update Android Studio to the latest version then follow steps below to create a C++ plugin.
1.Create a new Project in Android Studio
2.Check the Include C++ suport to enable C++.
3.On the Dropdown Menu, check C++ 11 on the C++ Standard drop-down menu. You will need C++ 11 to actually use most useful C++ features. Also, enable exception or frtti if you need them.
That's really it.
When you build the plugin:
The debug library is should be at:
\app\build\intermediates\cmake\debug\obj\
The release library is should be at:
\app\build\intermediates\cmake\debug\obj\
If you only see the debug but not the release version of the plugin, check here for how to make it appear.
Possible reasons you are getting DllNotFoundException on Android:
1.You did not wrap the C/C++ function around extern "C". You must do this for each function in the .cpp file or you do it in the function in the .h file.
2.You put the plugin in the wrong Unity folder.
The armeabi-v7a and x86 plugins generated at <ProjectDirectory>\app\build\intermediates\cmake\release\obj should be placed at Assets\Plugins\Android\libs\armeabi-v7a\ and Assets\Plugins\Android\libs\x86\ in the Unity project.
Make sure to spell these correctly. See this for more information about this.
3.You are loading it incorrectly from the C# side.
Let's say that the name of the plugin is libScreenshot.a, do not include the lib prefix, also do not add the .a when loading it.
[DllImport("Screenshot", CallingConvention = CallingConvention.Cdecl)]
public static extern void takeScreenshot();

Related

Include GStreamer in android ndk project that uses CMake (CMakeLists.txt) and not ndk-build (Android.mk)

I have an android project that currently uses Cmake for including all .cpp /.c code. Now I want to add the GStreamer native libraries such that I can use them in my native code.
But the gstreamer docs https://gstreamer.freedesktop.org/documentation/installing/for-android-development.html
only document using ndk-build to use gstreamer on android.
Now I don't want to totally refactor my project to use ndk-build and Android.mk because
CMake does its job and i never had problems with it
as stated here cmake is the default for android ndk https://developer.android.com/studio/projects/add-native-code
I also need to include the googlevr ndk library that uses cmake.
So I need to figure out a workaround and therefore need your help. Here are some ideas I came up with
Each module can have ether cmake or ndk-build support. Therefore,
I probably could add a new module using ndk-build and include gstreamer there (but then gstreamer is only available in this module)
Compile gstreamer for android using cmake inside android studio - but I don't see evidence that has been done before or is possible for someone without strong cmake knowledge.
Any other ideas/ improvements ? thanks
Even though you have already moved away from GStreamer but in case someone else is facing this issue please have a look at following github repository
https://github.com/henkeldi/gstreamer-android
For myself, I had to make two modifications
I modified the definition of GSTREAMER_ROOT to include ANDROID_ABI so it looks like following
#GStreamer
set(GSTREAMER_ROOT $ENV{GSTREAMER_ROOT_ANDROID}/${ANDROID_ABI})
I had to rename the folders in GStreamer pre-built binaries to be according to ANDROID_ABI. So, my Gstreamer pre-built binaries folder look like following
After the above changes, I am able to successfully build with APK with GStreamer using CMake
At some point I gave up on gstreamer and am now using ffmpeg instead.
There is a nice tutorial for compiling ffmpeg that makes including native ffmpeg inside an android project really easy:
Tutorial on Medium
Github project

How to Build CMake based project for Android/iOS using QtCreator

I have created a Non-Qt C++ (CMake) project using Qt, and I am able to build it using MinGW, MSVC compiler.
So in short, when I am opening my test project I can select the generators under Run CMake Window. I have issue with other platforms.
When I am trying to Add a kit for Android, there are no generators available in the list. I tried the same thing on Macbook, there also the same problem.
I need help on this issue, I couldn't get the proper steps to build the CMake based project for Android/iOS using QtCreator.
P.S. Installed CMake version is 3.2.1 and Qt Version is 5.5, I have installed Android SDK, NDK , and and Java
I would love to tell you "just check this box in the options dialog and it will work", but, unfortunately, there is no generator that you can use to build an Android/iOS project from a CMakeLists.txt file.
I found alternatives, in all cases, I don't think your have a chance to port a whole huge CMake-based project that used to work on Windows (with lots of libraries and 3rd party libraries) work on Android in less than a few days of work....;-)
Personnaly, I wrote a small CMake function generating the .pro file manually from my CMake scripts. It started small but is now huge and it's difficult to share it with you. But, basically, I started from this post on a Qt forum. It creates a simple .pro file that does not work that bad and then you can extend it for your own needs. I like this solution because I have full control on generated .pro file (mine can now build on PC, Android and iOS...but I had a hard time to have this fully work).
Apparently, there's also a way to add a Qt-android CMake support using this open source stuff: https://github.com/LaurentGomila/qt-android-cmake. But I never tried it. You may want to have a look to it. If it works, it may be more convenient that writting your own script generating .pro files. Apparently, it builds an Android apk using androidqtdeploy but without using QtCreator. There's also an iOS support.
Finally, the best may be to have CMake propose a QtCreator "generator" (it would generate .pro files, like CMake generates sln/vcproj files when using Visual Studio generator or makefiles for g++ generator....), but there is no such generator supported. I reported this to CMake team some time ago hoping they could fix that. I understood that there was and would be no plan to do that because CMake targets only "compilers" as "generators" and "QtCreator" is not really a "compiler", it's a "IDE" using external "compilers" to build (MinGW, MSVC, CLang, Android's NDK g++...). It's a shame because CMake known all your project information and could easily generate a .pro file....so, as, CMake is opensource, one may extend CMake with a custom QtCreator file generator...and share it with the whole world,it would be wonderful!
Hope this will help you!

How do i call C/C++ code from Android using JNA?

I'm trying to integrate this specific library to my Android project, and the library is written in C/C++. I've miraculously gotten ndk-build to give me the needed .so file.
However, looking at it, there's a sample in the project, and they use a mysterious .jar with the API bindings of the .c/c++ files.
How do i either
create this special .jar file that has the API, based on the .so?
OR
directly add a method to the main c++ file and then call it from Java?
I've tried to re-wrap things using JNI, but it definitely doesn't seem to work. i keep getting UnsatisfiedLinkError.
A lot of the documentation online uses jni as the tutorial. i'm happy with just a few links to tutorials on JNA.
JNA provides a stub native library, libjnidispatch.so for a variety of platforms. You can build this library yourself, or extract one of the pre-built binaries from the project's lib/native/<platform>.jar packages.
You include libjnidispatch.so in your Android project the way you would any other JNI library. This is required; you cannot rely on JNA to dynamically unpack and use its native library automatically like on other platforms. The JNA project includes details for doing so (as well as instructions for building libjnidispatch.so yourself).
You then use jna.jar as you would any other Java jar file, and write your own (Java) mappings to match the native library you're trying to access. There's also a jna-min.jar which omits all the native platform libraries that are normally bundled in jna.jar.
Do go to project properties and build paths and remove JNA 4.0 and related classes.
This will work!

How to build static library from C++ using NDK on Android using Android Studio with Gradle?

I have a project written in C++ and I want to build a static library to be able to link against it in other projects. But Android Studio along with NDK produces only shared library objects which are for me not usable (I need static objects). I use gradle plugin to build the code.
While the code compiles I cannot find a way to get a "libname.a" file.
Anybody knows the magic behind this in Gradle ?
While not well familiar with the NDK Gradle supports building native static libraries. You can see an example in C++ with Gradle or learn more about it in gradle user guide Native Binaries chapter.

Android Studio use shared library in NDK code

Basically, I want to know how to use a c++ shared library in Android Studio in NDK code (inside jni part). There is quite a lot of questions about that but they all are based on changing Android.mk which is not a way to go because in AS it's generated automatically.
To use pre built librairies with Android Studio, you have to follow these steps:
Compile your C++ librarie with ndk-build (here you build librairies for Android architecture such like arm, x86, etc.).
Create a Java class and JNI wrapper for your C++ methods.
You have then to disable gradle for ndk-build and create your own Android.mk and Application.mk in the jni folder.
Import the .so library and pre build it in the Android.mk.
Invoke ndk-build manually, from the Android Studio console.
Then, include the header of your librarie and call its functions in your JNI part.
For any complement of information, I advise you the intel video that you can find here.

Categories

Resources