I need to add my native library to Android source for others applications can use it (call functions from this library in their code). I need to use library like embed without adding it to every project in that I want use it. But i can't find information about this.
Please give me information how to do this. Sorry
As far as I understand, what you are trying to do is to run c/c++ code on Android. Am I right?
To be able to do that, you should use Android NDK to build your native library, and then load it into java code.
You need to follow 4 simple steps to run native code on android, after installing ndk:
1) Create Java "wrapper" for your native code - for. eg. create class named MyNatives which will hold method declared with native keyword. This tells the compiler, that implementation of this method is done in native library. Create static initializer, which will load the library. eg:
public class MyNatives {
static {
System.loadLibrary("hello-jni");
}
public void native nativeMethod(int x);
}
2) Compile the code, and run tool called javah for your native class (there are some plugins for eclipsee which will do that for you, eg. sequoyah)
cd <your project path>
mkdir jni
javah -d jni -classpath bin/classes com.example.MyNatives
This will generate header in jni directory (all native code in android project should be inside this direcotry)
3) Add implementation of your method from generated header
4) Create makefile for android build system and build library. Makefile should be named Android.mk. It makes use of some specific variables and macros, for more info please see NDK documentation, eg:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# your library name
LOCAL_MODULE := hello-jni
# all source files
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
to buld library just call ndk-build from project root directory
For more info, please see Android NDK documentation. Hope it helped a little.
Related
I'm struggling with this for several days now. At the moment i'm just testing it with a simple C++ project (1 .h & 1 .cpp file) and a minimalistic App including the ndk helloJNI sample code (which worked perfect easily):
Target
Import existing C/C++ files (project) to Android Studio
Approach
After trying out some of the (dozens) of different possibilities, i think/thought the following steps would be the best solution for my purpose:
Create the shared library (Calculator.so) from Visual Studios 2015 "Create shared library for Android" (or something) [successful]
Create jniLibs folder in src/main/ with its subfolders (x86 the relevant one in my case)
Add the Android.mk file in src/main/jniLibs which has to be placed there (?)
Include statement: System.loadLibrary("Calculator") without "lib" and ".so" in MainActivity
The library is listed in Android Studio in its folder jniLibs as like the Android.mk. Moreover if i build the apk, the library is successfully packed (verified by unzipping) and i dont get any errors.
BUT: how can i call the methods in the library? I tried the different solutions offered in other threads, but i think i missed something in my .mk or my steps described above.
Tried
Different #include <myLib> statements in native-lib.cpp, like s
Different Android.mk settings (but i'm new to make files so not even tutorials helped me much with my specific problem ::) )
Other locations for the libCalculator.so like in the subfolder x86
and many others - simply not reminding atm (wasntme)
Your help is highly appreciated!
Android.mk
LOCAL_PATH := $(call my-dir)
APP_ABI := x86
# library info
include $(CLEAR_VARS)
LOCAL_MODULE := Calculator
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/Calculator.so
LOCAL_EXPORT_C_INCLUDES := ..../Visual Studio 2015/Projects/SO_Library/SO_Library
include $(BUILD_SHARED_LIBRARY)
There are lots of things, you can do in Android NDK. For example, Camera hardware is one of the heaviest hardware in Android OS. Detecting faces, things, giving effects and for thousands of features NDK is the best.
Some helps for your steps:
You can built and prebuilt shared(.so) and static(.a) libraries in Android Studio also. Not need Visual Studio.
Don't create jniLibs folder in main folder. When you build your project via gradle, it already creates this folder and put your target libraries. If you want prebuilt any libraries, put these libraries in main/jni/libs folder and prebuilt then with Android.mk.
Don't add the Android.mk file in jnilibs folder. Create this file in main/jni folder. Also Application.mk file.
Call your libraries, in any activity, where you need, in static method. Like this:
static { System.loadLibrary("my_library") }
Without "lib" and ".so" extensions.
When you want to call your native methods, just use "native" keyword. For example:
private native int nGetNumberFromNativeSide();
Just call this method, where you want, and get result. But for ndk building in gradle side, look at this answer. For building library in Android.mk, these sample lines maybe help you:
include $(CLEAR_VARS)
ifneq (,$(filter $(TARGET_ARCH_ABI), armeabi-v7a x86 arm64-v8a x86_64))
LOCAL_MODULE := my_library
LOCAL_SRC_FILES := $(LOCAL_SRC_LOCATION)/native1.cpp native2.cpp
include $(BUILD_SHARED_LIBRARY)
You can put name anything you want, but dont add lib and .so extensions. Ndk is already doing it.
I have already gave Android.mk example.
When you build Android.mk file, it locates your libraries appropriate folder. Like main/libs/x86/libmy_library.so.
I guess this answer will help you. If you have more questions, add to comment, i'll edit my answer and add answers.
I'm trying to compile an open source project (let's say foo) into a libfoo.so native library to use for my android app. However, this project also uses google's protocol buffer library.
So i was able to compile Google's lib protobuf for iOS as follows: https://gist.github.com/BennettSmith/7150245 .
However, this just generates libprotobuf.a file. The problem is that I can't seem to figure out a way to include this libprotobuf.a file to my libfoo.so file for use with my android application. I THOUGHT i had referenced it when i did:
include $(CLEAR_VARS)
LOCAL_MODULE := libprotobuf
LOCAL_SRC_FILES := ./src/lib/libprotobuf.a
LOCAL_EXPORT_C_INCLUDES := ./src/include
include $(PREBUILT_STATIC_LIBRARY)
in my Android.mk file. However, it seems that it is definitely not getting linked properly. Whenever i try to ndk-build the open source project (which depends on using lib protobuf), i get a bunch of undefined references, like:
undefined reference to 'google::protobuf::internal::empty_string_'
so then i thought that maybe i'm not supposed to have the symbols defined here? like maybe i'm supposed to first compile the libfoo.so file, and then somehow link lib protobuf as libprotobuf.a or libprotobuf.so ?? so i ended up using LOCAL_ALLOW_UNDEFINED_SYMBOLS := true to just get my project to generate the libfoo.so file.
but this libfoo.so gives me some load error as soon as i try to use it within my android app:
dlopen failed: cannot locate symbol "_ZN6google8protobuf11MessageLite15ParseFromStringERKSs" referenced by libfoo.so
So I'm wondering:
How do i include this protobuf library in my android app?
Do i try to include this protobuf library into libfoo.so first?
Would it even work if i tried to ignore linker warnings and then tried to generate libprotobuf.so and include that with my application?
is it even possible to generate libprotobuf.so? I can't generate it using the instructions on their github - i get a ton of errors
Note that the only reason i'm even able to get undefined reference errors when trying to generate libfoo.so is because i manually copied all of the *.h in google's lib protobuf.
Any help would be greatly appreciated!!!
I wanna realize this idea. I spent several days searching for information, but could not find anything. All tutorials say how to write my own library with JNI, but how to wrap already existing? I need just simple tutorial step by step (and why? if it possible). So I wanna start create native android application.
What I have :
I create C++ library in QTCreator by tutorial from youtube: simple library on C++ (.so) with headers (.h) which do simple cout in console:
Not compiled code mylib.cpp:
#include "mylib.h"
MyLib::MyLib() { }
void MyLib::Test() {
qDebug() << "Hello from our DLL";
// .so
}
Header mylib.h:
#ifndef MYLIB_H
#define MYLIB_H
#include "mylib_global.h"
#include <QDebug>
class MYLIBSHARED_EXPORT MyLib
{
public:
MyLib();
void Test();
};
#endif // MYLIB_H
and mylib_global.h (I think it does't matter)
So after build I have myLib.so.
And now I need wrap it in my android app. So I don't understand what I need to do for it.
I'm develop in Android Studio. And what I know:
Create in java package LibWrappClass with native method - something like "simplePrint()":
public native void simplePrint();
I need to create in /src/main folder "jni". Create Android.mk, myLibWrapper.h and myLibWrapper.cpp. But I don't understand what I need to write in Android.mk for connect my myLib.so to "myLibWrapper.h", and where should I put my library with headers. Can anyone help?
After adding the native method in your java code, You simply build the project. Now you need to move to the location where the class files are written by your IDE. Since you use Android Studio, it must be somewhere your project folder with path
out/production/YourModuleName
Open the location in commandline and run the javah command to generate the header file for your native function
javah -d <your jni folder path> <com.YourPackage.YourClass>
The class YourClass should be where you have declared the native method. This command will create a header file with name something like com_YourPackage_YourClass.h with a function declaration looks like
JNIEXPORT void JNICALL Java_com_YourPackage_YourClass_simplePrint
(JNIEnv *, jobject);
Implement this function in a C/C++ file with whatever operations you have to perform on jni side.
Then, Define the Android.mk file, In this case it will be something like
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := lib
LOCAL_SRC_FILES := lib.c
include $(BUILD_SHARED_LIBRARY)
If you have multiple source files add them in LOCAL_SRC_FILES separated by space.
Next, go to your jni folder and build the project using command ndk-build. This will place the .so file inside the android folder libs/armeabi
Finally rebuild the Android project from Android studio and run.
For detailed instructions and complete source checkout this gist
I have written C++ file in JNI folder of my application. I am using Windows system with NDK and Cygwin 1.7.I want reffer to CURL library available in Cygwin.How can we refer to external .h(libraries/header) files while creating JNI application in Android?I have created a combined Android and C++ project. But I am referring CURL header file. When I build the project I am getting fatal error: curl/curl.h: No such file or directory issue.
Follow these steps:
Converting from Android project to C/C++ project:
Right click on your project name, go to 'Android Tools' and click 'Add native support'
Adding paths to external .h files:
Right click on your project name, go to 'Properties', under 'C/C++ General', go to 'Paths and Symbols', under 'Includes' tab, add the folder in which your .h file is. Remember to add to all languages and configurations if asked.
Also, since you are in Windows, I think you will need to change your Build command (which is in the 'C/C++ Build' section in project properties) to "bash C:\Development\android-ndk-r8\ndk-build.cmd"
Add the following to your Android.mk:
LOCAL_CFLAGS += -I$/PATH/TO/YOUR/curl.h
LOCAL_LDLIBS += -L$/PATH/TO/YOUR/libcurl.a.for.android -lcurl
The libcurl.a you have installed in cygwin is not usable for android, you need a version targetting android. If you don't have it, build it yourself.
When you get that libcurl.a file, do not forget to copy the headers folder of curl (get into your usr/include/curl from Cygwin) and add this folder to the JNI one in your project, so it knows the headers while compiling.
Which means also referring in your Android.mk :
for the libcurl library
LOCAL_SRC_FILES := libcurl.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/curl
and for your C++ files
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/curl
LOCAL_WHOLE_STATIC_LIBRARIES := libcurl
Please used this tutorial is nice one.
Don't forgot to change this setting after convert project to C / C ++ native project.
Builder Settings to Build Command
bash C:\tools\android-ndk-r8b-windows\android-ndk-r8b\ndk-build
This is my path of NDK you can change this path accordingly your NDK path.
I'm experimenting with a rooted Android tablet. I need to run some system applications in C/C++ that can run as native apps with/without using the NDK. This would work like existing command line applications such as toolbox as a native ARM Linux executable.
Is that a possibility?
Yes, you can. And you can do it using the NDK which you make things easier to you , cross-compiling to all platforms supported by Android (ARM variants and x86). You just need to do like you would do to create a shared library for native Java methods. Just make sure you change the makefile to use BUILD_EXECUTABLE instead of BUILD_SHARED_LIBRARY to create an executable. Of course you won't need the APK folder structure, just the "jni" folder.
Tutorial
Create the project folders:
mkdir project_folder
cd project_folder/jni
NDK_PROJECT_PATH=<path to>/project_folder
Create the Android.mk makefile in the jni folder
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := teste
LOCAL_SRC_FILES := teste.c
include $(BUILD_EXECUTABLE)
Create also your source code in the jni. In this case, you can see from above makefile, it is teste.c:
#include <stdio.h>
int main (){
puts("Hello World");
return 0;
}
Now go up to your project folder and run ndk-build from there:
# ~/Downloads/android-ndk-r8b/ndk-build
Compile thumb : teste <= teste.c
Executable : teste
Install : teste => libs/armeabi/teste
Although it is output to a lib folder it is a executable, as you can inspect with file
#file libs/armeabi/teste
libs/armeabi/teste: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
Yes, it's possible. When you download the NDK you get a set of tools (compiler, linker, etc.), headers and libraries. It's not significantly different from other cross compilation environments.
The NDK comes with a cross compiler and enough of a freestanding programming environment (includes and libs) to port simple C/C++ applications to run as native Android binaries. Check out the docs/STANDALONE-TOOLCHAIN.html file in the NDK for documentation. (It's available online at kandroid.com.)
I believe that the NDK does not have access to enough system services to write a complete app. You'll still have to write the scaffolding of the app in Java, but you can write plenty of native libraries for the Java to call.