I am using C++ to code in Android (I am using cocos2d-x, specifically).
Now, say, I have a class, MyClass, with .h and .cpp files. I would like to create a .so out of these files. Then, I would like to include that .so in my project and access it via #include "MyClass.h". Is it possible? If so, how? Thanks!
To build your static library for ARM you can use the NDK standalone toolchain.
Once you've compiled your .so, you can include the library in your project using the Android NDK make file (Android.mk) which will look like the following:
LOCAL_PATH := $(call my-dir)
LOCAL_SRC_FILES := my_module.so
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
You'll want to make sure you include the headers (/include) in the right path.
Not sure if your intent is to ge back into Android-land with your code, but if you're looking to create a bridge between your .so/C/C++ code and Java, you'll need to describe the appropriate JNI methods in C, build out the necessary Java classes with the static System.loadLibrary('my_module') imports and native method declarations mapped to your JNI methods.
Related
I found instructions for how to link and use c/c++ code in Android by utilizing the NDK. But I'm searching how call function from third party .so .
For example your prebuilt library is called "libmy.so"
In the project folder of the project you want to use it:
1) create libmy folder in jni folder (jni/libmy)
2) copy your libmy.so here
Then, just create a jni/libmy/Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libmy
LOCAL_SRC_FILES := libmy.so
include $(PREBUILT_SHARED_LIBRARY)
Now in your jni/Android.mk you can write:
LOCAL_SHARED_LIBRARIES := libmy
Then when you do ndk-build, it will copy this library in to libs/armeabi/
After that you can use this library in your C++ code.
You just have to put the .so in your libs/armeabi-v7a folder (or whatever other architecture you have compiled for, like armeabi, x86 etc.) and Eclipse will automatically see it and integrate it into the APK.
Then to access any native functions from the .so in your Java code, you just have to declare it as a native function at the top of your class. For example
protected static native void AKUAppInitialize ();
which can then be called anywhere later in the code like
AKUAppInitialize();
You have to configure your NDK part if you have the source code: look at this tutorial
I want to create a c++ project for android ndk.And I want to use it every project like dynamic library.I dont want to change /transport source code every time.I import *.so file and include it and use its class or whatever.
This is possible.If it possible how could import and use it.
Or i create java project and i use it to communicate c++ project with using jni and i compile it.After that i have a *.jar file and i use it instead of android ndk.
Which one of them possible or effective.
I'm not entirely sure if I understood the question correctly, but I assume you prefer to write your Android applications using solely/mostly C++ and have a core library/module that you want to re-use for every consecutive project WITHOUT including that libraries SOURCE files in each consecutive project.
You can omit including the source files and include the final built .so file in your new project by adding the required libraries into your makefile. Like so:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := (includes for libraryname)
LOCAL_MODULE := libraryname
LOCAL_SRC_FILES := libraryname.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
--- instructions for custom application code here ---
LOCAL_SHARED_LIBRARIES := libraryname
Where "libraryname" is the name of the library module and "libraryname.so" is the name of the library file. Note the path should be relative to the make file. Below the second "include $(CLEAR_VARS)" and above the final "LOCAL_SHARED_LIBRARIES" you add the instructions for building the source code of the application which is to use the shared library.
Don't forget to load all libraries in order on the Java side, i.e.:
System.loadLibrary( "libraryname" );
System.loadLibrary( "customlib" );
I'm a bit confused with what I'm currently attempting: I want to cross-compile a C library for use with Android through the NDK, so that I can create a JNI wrapper and call some of its functions from my Android java code.
I followed this guide to crosscompile libopus (the library I want to include in my project): http://mortoray.com/2012/08/21/android-ndk-cross-compile-setup-libpng-and-freetype/ which means I currently have a standalone toolchain at /opt/android-ext/, with a lib folder that contains the library I cross-compiled (libopus.a, libopus.so, etc).
I also already have a jni folder on my Android project, which contains some C code with the JNI bindings that I want, and that I can call from my Java code, but it does nothing (I can call it but it's a blank function). This means that in my project, there's a /lib/armeabi directory with "libopusUtilsNative.so" (the wrapper).
My question is:
How do I add the library that I just crosscompiled to the project, so that (for example) I can just do an #include call on the C source code file that I already have and get access to the library functions? I'm a bit lost with how to:
Include the library I cross-compiled into my project.
How to make the wrapper code I created include it (I'm guessing this has something to do with adding some code to my Android.mk file, but I'm clueless).
The guide that you linked to contains an example of how to modify the Android.mk file for your JNI library (or in his case, a native app) to link against the cross-compiled library:
PLATFORM_PREFIX := /opt/android-ext/
LOCAL_PATH := $(PLATFORM_PREFIX)/lib
include $(CLEAR_VARS)
LOCAL_MODULE := libpng
LOCAL_SRC_FILES := libpng.a
include $(PREBUILT_STATIC_LIBRARY)
# The in your project add libpng
LOCAL_STATIC_LIBRARIES := android_native_app_glue libpng
That's pretty much how you'd do it if you wanted to link statically against libopus. Or if you want to link against the shared library, use something like this: Using my own prebuilt shared library in an Android NDK project
I'm currently implementing a custom Logging mechanism that I need to be accessible from both native and Java code. The fundamentals of the logging are implemented in C/C++ with a Java wrapper, and the two together are being built as an android Library Project.
The issue at hand is that while my Java code can access the Library project output, there doesn't seem to be a way for my native code to access the native .so or headers from the Library project. Is there an additional step I'm missing or is this just a limitation of the current ADT? More specifically, is there a makefile/eclipse configuration that will address the things I'm used to getting out of Library projects in general? (Build .so as needed, import rebuilt .so, import relevant headers for c/c++ compilation, etc.)
I don't think it's a limitation. We are supposed to declare native code dependencies in Android.mk and Application.mk
Worked out a way to get what I wanted - most of the information is (of course) in the NDK documentation, but what I was trying to do isn't 100% supported within the ADT. It should also be noted that I'm currently stuck developing in a windows environment, so much of this might be easier or unnecessary in Linux. The first key is the $(call import-module ...) macro. Within your library project, move the source files and the Android.mk folder into a named directory you can locate later. My Library project directory looked like this:
MyProject
> src
> res
v jni
- Application.mk
v MyLib
- source.cpp
- source.h
- Android.mk
I also had to edit my Application.mk to point to the project:
APP_PROJECT_PATH := <path-to-my-project>
APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/jni/MyProject/Android.mk
Annoyingly, this broke my Android.mk in ways unforseen until I added a ./ to my source files. Also you need to export your includes for linking:
LOCAL_SRC_FILES := ./source.cpp
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
Ensure that the system path variable NDK_MODULE_PATH is set to include your library's JNI directory, e.g. <path-to-my-project>/jni (Note: I had to restart eclipse after I did this).
In the receiving application's Android.mk file (the one you'd like to link natively to your app), import the module:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyNativeProject
LOCAL_SRC_FILES := source.cpp
LOCAL_CFLAGS := -DANDROID_NDK -g -std=c99
LOCAL_SHARED_LIBRARIES := MyLib
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
$(call import-module, IntelLog)
At this point everything built perfectly, but the APK packager didn't like the generated .so binary being included twice (once from the Library project's natural import process, and again from the import-module call). To solve this, clean the library and don't build it again! the import-module call will build the .so and import it into your project. (Obviously, if your project only requires the Java API, you would need that .so file to be built). Congratulations! you have a functional (if not straightforward) build process with a hybrid native/Java Library
I have created static library of one of my project say libABC.a. Now i want to use this static library in another android project at jni layer. The second project would also have its own .cpp files inside jni folder, which would be using the functions of libABC.a static library. Now my question is what are the steps through which i can include static library into another project at jni layer ?
You can use PREBUILT_STATIC_LIBRARY in your Android.mk file.
They have a very detailed explanation in android-ndk/docs/PREBUILT.xml
In short you add to your Android.mk something like
include $(CLEAR_VARS)
LOCAL_MODULE := anynamehere
LOCAL_SRC_FILES := yourlib.a
include $(PREBUILT_STATIC_LIBRARY)
before your module