Referencing Native Libraries within NDK project - android

I am trying to reference native libraries from within an NDK project using CMAKE, but I am not having much luck. My first attempt was to simply add the include for the native library I was interested in. (for example)
#include <multinetwork.h>
However, that didn't work it simply said file not found. So, would it be something I put in the CMakeList.txt? Just to be clear I want to reference native library methods/classes DIRECTLY from my C++ code in my NDK project.
P.S: (READING PAST HERE ISN'T NESSASARY IT JUST ADDS MORE COLOR ON WHAT I AM GOING AFTER) I feel like I should share my true objective is to gain access to things not allowed through the application framework. I want to override/use classes in the native libraries that I am not given access to. I am hoping I don't have to recompile kernal to do this.

Try to use:
#include <android/multinetwork.h>

Related

How to publish Kotlin + JNI android library to Bintray?

I've been developing a library to use in my project, and while it is working locally, I would like to share it and use it as an external dependency.
How do I wrap my library so that built AAR contains both *.so native library and generated *.java classes (generated by Kotlin compiler) ? Because there are two-way interactions in my library: Kotlin external functions defined in C++, and some C++ code calling Kotlin classes and methods.
So, my questions are:
How to correctly package Kotlin + JNI android library ?
How to upload said package to Bintray so users (and myself) could use it as a dependency ?
(Note: I've seen tutorials and examples, but they were either Kotlin/Android or Java/Jni/Android)
If you want to package .so with your application, note that you can always put it inside JAR file. Then, you can unpack it, and load it using System.load.
You can find sample here: https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo031
Note
Remember that packaging .so inside application is a risky thing. As you deal with native code, you have to be 100% sure that all native dependencies are there. You have to pay attention to architecture as well.

Android Studio JNI: cannot compile JPEG c-library

My program needs to read jpeg-images from a file native. For that purpose I downloaded official jpeglib c-source code and that works flawlessly on a Windows version of this program, which is programmed using Embarcadero RAD Studio 8.
But when I try to use the same source code in Android Studio JNI, I see lots of errors almost every c-source file :( Below is a screenshot:
As you can see, there's errors on both
-Macro expansions (ERREXIT, red underlines), which complain "class 'blahblah' doesn't have a field 'blahblah'".
-member methods (red text in code), which complain also "class 'blahblah' doesn't have a field 'blahblah'".
Looks like there are many C-language classes and fields, or probably all, which are not working. But the jpeglib source definitely contains them all, something is just not working in Android Studio! Probably Android Studio C-compiler is somehow limited, but there must be some way to bypass it...
This problem doesn't exist in C++ source files. I have different source folders for java and C++ source files (and there are also separate jni folder, but I don't use it, probably I should), but C source files resides inside the C++ folder. I have added all c, cpp, h and hpp source files inside the parentheses of the CMakeLists.txt's add_library() directive, but that's all. I don't know is it enough...
I'm glad to get any suggestions how to fix this.
It is not enough to add all libjpeg files to your add_library(). The library expects to be configured for the specific toolchain, see e.g. this example.
I prefer an optimized version of the library, called libjpeg-turbo. On GitHub you can find step-by-step instructions how the library can be cross-compiled for Android.
Well, there seems to be happy ending...
I have to admit that Android Studio most likely can compile JPEG c-library:) The problem "class 'blahblah' doesn't have a field 'blahblah'" was because the library needs to be configured for the specific toolchain, like #Alex Cohn said. But the configuration doesn't happen in CMakeLists.txt, instead you need to rewrite the code itself at some extent. For example, you need to change
-INT32 to int32_t
-#define boolean bool
-#define EXTERN extern
-add lots of #include <> and #include ""
-and more...
If you need to do that, start from header files: don't touch C files until you have headers error free. As a side note, I had exactly the same build order in Android Studio than I had in Embarcadero Studio, but that didn't helped to succeed... I don't know yet, will this modified library work, but at least I think I will get rid of compilation errors!

How to properly setup dynamic library loading with header file?

The title was tough to get right, so let me explain my situation:
Another team develops a library. They ship a header file and a *.so file. The header file is available to us, and we can include it in our own code and use it if we wish. The *.so, however, is shipped with the platform we run on. We do not have access to this *.so at build time for our software. Because of this, we can't really use the header file either, since the linker will expect the *.so to be available at some point.
Right now what I do is create a wrapper class that loads the *.so file at runtime, then uses dlsym() to find functions by name, and I map them to function pointers.
Is this the only option? Is there a way I can use the header file but tell the linker to not resolve the symbols at build time, but instead try to resolve them at runtime after we have a chance to load the *.so file?
Note the real platform here is Android (via NDK), but hoping general linux advice will work as well in this case since we have POSIX APIs available.
You have a few options, in order of preference:
Get the libraries from the maintainer. Providing the header but not the library (at least a stub library like we do for libraries in the NDK) just won't work.
Build your own stub library. It's pretty straightforward if you have a list of symbols to expose. Put int foo; void bar() {} in a C file for all the variables and functions you need to expose and build it as a shared lib. If you have the list of symbols in a version script, you might be able to use Android's gen_stub_libs.py to do it for you.
Mark all the symbols with __attribute__((weak)) in the header file. The linker won't complain that they are missing. If they're missing at runtime, the library will still load but each function's address will be nullptr. Not really what you want in most cases because if your definition of the library is wrong, you turn build time failures into runtime failures, but in some cases this can be handy because it's easier to check for function availability with if (foo) { foo(); } then to do similar with dlsym.
Add -Wl,--allow-shlib-undefined to your ldflags. This is even worse than 3 because it affects all the libraries you link, but it wouldn't require you to meddle with the header.
On Windows this is solved by requiring export library (.lib) to be present for linker instead of real dynamic library (.dll). I think you can try making something similar, that is making a fake .so containing stubs of all the methods exported from real .so and linking against it. This hopefully will make linker happy and at the same time at runtime application will load real .so.

How to use/incorporate CPP files to Android project?

We have developed an iPad application where the core logic is written in CPP code, so that we can use the same code files/libraries to other platforms.
Now I want to use those files and develop similar Android application, but unable to create .so files and integrate paths in Android.mk files and all. I am basically an iOS developer, this is first time I am looking into Android NDK.
Can anyone help and guide if there is any straight forward steps to it.
I have already gone through android developers site and few other tutorial sites. But none of those worked for me.
Require easy-clear steps to call cpp method in java, if I do have few cpp files and .a libraries with me already.
You aren't very specific at the step you are stuck at.
Here's a very quick explanation on how to call native code from java (android) :
first create a method to be exported by the native and called by java (this uses JNI, so google JNI , JNIEXPORT)
once you have this method defined in your native code, it's time to create a shared library (.so) file , using the compiler that comes in the NDK (because you are compiling for android ). You will need to compile for the correct architecture of the device (armeabiv7s is the most common now days).
you need to add the library file in your app.apk inside the armeabi folder (more details in NDK tutorials).
inside your java code you will need to load the shared library via the System.loadLibrary(LIBRARY_NAME);
inside your java code you will need to have defined static native methods that are in pair with the methods you exported from your CPP code
Quick tips :
use C functions,not CPP , since CPP will be mangled in the resulting shared library. In other words, you will need to create a C wrapper that will call your cpp code.
look over a hello world tutorial for NDK , and work yourself from there . Here's a link to such tutorial http://trivedihardik.wordpress.com/2011/06/16/hello-world-example-using-ndk-in-android/
You will bump later on into compilation issues with the makefiles, but by then you will probably be able to be more specific with your question.
Easiest way is to use the hello-jni Android studio sample project.
There are a lot of settings and configurations, you get them from the sample that is a working unit, always easiest when starting from something working.
First run (and modify) the hello-jni and learn how the interactivity between the Java and C parts works. About everything works except environmental ANSI C/C++ stuff. You have to get things like language, country etc from Java and transfer it to the C-code. You are in US in English with "inches and gallons" in JNI.
Then to an own project you create with android studio, copy and modify from it bit by bit from hello-jni. When you have our own branded hello-JNI you can add bit by bit your own code. Often using C-dummies for testing the interactivity with the Java part is easier, then change it to the real C/C++ code of yours.
Read the Android/Android studio documentation and learn and understand. Use the Android emulators, much easier and they are good.
The project configuration stuff is by far the hardest to handle at the start. If I would make a new project today, I would start from the Hello-JNI once again.

How can I separate JNI part from the Android app?

I am writing an Android application. I am implementing some of the app in C++ using JNI. Is there a way to actually separate completely the JNI (C++) code from the Java Android code? Like creating a JNI project or something ? Because my C++ code will become a little library that I will use in another app. I tried to create a C++ project but I can't compile with ndk-build.
In actuality, the tie-in between the Java and native code is fairly loose, in that it is done by the names of the methods at runtime.
The NDK is just a special environment and libraries for a C compiler. A suitable dynamic library file must be produced, but this can be done using the ndk script, using an ndk generated "stand alone tool chain" or even done before (or after, see later) the java project build, done on another machine, etc.
Normally the .so dynamic library gets copied into the appropriate place in the application project tree such that it will end up packaged in the .apk and installed on the device where it can be automatically found by the System.loadLibrary() method. But you could just insert it into the otherwise finished .apk (which is a zip file with special alignment and jarsigner signatures). But even the .pak is not actually not the only way to deliver it to the device (though it is the only recommended way)- a library can also be stored in a place such as the app's private folder and loaded using System.load() which takes a full pathname instead of a library name.
hotverspicy does have a point that the java code needs a native method "declaration" for what is implemented in the jni library, and that this needs to match the actual package name as encoded in the name of the native function implementation. However, that package name does not have to be the same as the rest of the java code - it could be something generic for the re-usable C/C++ library, which would require only one brief matching java class file in the matching java package name.
But in addition to Neevek's idea of using one native lib to interface to another, it is also likely possible to use an object factory mechanism to hook up arbitrary native functions at runtime, given just one association set up at compile time - see the relevant answer to C/C++ Reflection and JNI - A method for invoking native code which hasn't been written yet
If you use JNI in your C++ code, then it's bound to Android, and it must be an Android project with properly defined Android.mk, Application.mk(optional).
If you don't use JNI API in your code, say you want to create a generic library, you can just write your C++ code, compile it, test it as usual, no ndk-build is needed. When you finish coding with the library, build the code as a static library, and when you want to use this static library in your Android project, write some JNI wrappers around functionalities in the static library that you want to use, link against the static library in your Android.mk, something like this:
include $(CLEAR_VARS)
LOCAL_MODULE := libgeneric
LOCAL_SRC_FILES := prebuilt/libgeneric.a
include $(PREBUILT_STATIC_LIBRARY)

Categories

Resources