NDK - linking a shared library
Only the JNI function itself should be marked as extern "C"
, like here:
#include <jni.h>
#include <string>
#include <sstream>
#include <get13.h>
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_semko_myapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject asdf) {
get13();
return 1;
}
If you use javah to prepare a MyApplication/jni/native-lib.h
for you, it will have
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_semko_myapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject asdf);
for you, and in the cpp file, you will
#include "native-lib.h"
and don't need extern "C"
at all.
To make sure that your Android.mk is valid for all architectures, consider this change:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libhello
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libhello.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := native-lib
LOCAL_SRC_FILES := native-lib.cpp
LOCAL_SHARED_LIBRARIES := libhello
include $(BUILD_SHARED_LIBRARY)
Update: the important piece is include $(CLEAR_VARS)
before LOCAL_MODULE := libhello
.
Android NDK - Error Linking Shared library and JNI Wrapper
Instead of using the ndk standalone toolchain, I used the ndk-build on my build machine which then generated the libs file I needed. From there I added the libs file with the contents of:
- arm64-v8a
- armeabi-v7a
- x86
- x86_64
Into my Android directory under src>main>jniLibs which then stored all the files and just added the command to my app build.gradle:
sourceSets.main{
jniLibs.srcDir 'src/main/jniLibs'
}
For ndk-build to work properly I had to include the jniWrapper.c file.
Android.mk:
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := testing
LOCAL_SRC_FILES := jniWrapper.c \
testLib.c
include $(BUILD_SHARED_LIBRARY)
Application.mk (I was testing with "all" but its unneeded):
APP_PLATFORM := android-23
APP_ABI := all
I know this is a work around solution but for some reason I could not figure out the toolchain to work correctly.
Android NDK error when linking shared C library
I think you misunderstand the cmake syntax. Below is enough for your case.
target_link_libraries(
main
${log-lib})
Below are source files, NOT library names.
communication_api
cybtldr_api
cybtldr_parse
cybtldr_command
So, you cmake statements are not correct.
If you want to make less confusing, try to make below changes.
find_library( # Sets the name of the path variable.
log-lib
log)
add_library( # Specifies the name of the library.
my-native-lib SHARED
main.c
communication_api.c
cybtldr_api.c
cybtldr_parse.c
cybtldr_command.c
)
target_link_libraries(my-native-lib
${log-lib})
But, remember to change your Java side as well, see below example:
// Used to load the 'my-native-lib' library on application startup.
static {
System.loadLibrary("my-native-lib");
}
I just enclose my JniExample project in case you need: https://github.com/russell-shizhen/JniExample
How to link Android NDK shared library?
I found a way to link. If I make a directory named jniLibs inside app/src/main and then copy all the share library in side. It is able to link and load library. Note that directory name "jniLibs" is case sensitive.
You must call this in source code:-
static{
System.loadLibrary("libray_name"); // without prefix 'lib' and suffix '.so' i.e. "libLibName.so" should be only LibName.
}
Linking VTK with ndk-build on NDK r17c results with 'undefined references' errors
I ended up using CMake insted of ndk-build.
I needed to add this code to my module's build.gradle:
android {
...
defaultConfig {
...
externalNativeBuild {
cmake {
cppFlags "-std=c++11"
arguments "-DANDROID_CPP_FEATURES=rtti exceptions",
"-DANDROID_STL=gnustl_shared"
abiFilters 'arm64-v8a'
}
}
}
...
externalNativeBuild {
cmake {
path "src/main/jni/CMakeLists.txt"
}
}
}
And, my CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 3.4.1)
set(LIB_DIR ${PROJECT_SOURCE_DIR}/lib/${ANDROID_ABI})
add_library(vtk-common-color STATIC IMPORTED)
set_target_properties(vtk-common-color
PROPERTIES IMPORTED_LOCATION
${LIB_DIR}/libvtkCommonColor-8.90.a)
#53 more libraries
add_library( vtk-lib SHARED ${PROJECT_SOURCE_DIR}/vtk-lib.cpp)
target_include_directories(vtk-lib PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(
vtk-lib
-Wl,--start-group -L ${TARGET_OUT}
vtk-common-color
#53 more libraries names
-Wl,--end-group
)
Android: Linking to prebuilt static libraries
Your libraries are interdependent:
Lapack requires Blas
Mumps requires Blas and Metis
Ipopt requires Mumps, Metis, and Lapack
This means that the order for linking them should be reverse:
ipopt
mumps
metis
lapack
blas
If you don't want to waste your time on figuring out the best order, but rather let the linker to find out (this may slow your builds significantly), you can use
target_link_libraries(native-lib -Wl,--start-group
blas
lapack
metis
mumps
ipopt
-Wl,--end-group).
You can also teach CMake about the dependencies between imported static libs, via IMPORTED_LINK_INTERFACE_LIBRARIES, e.g.
set_target_properties(lapack
PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES
blas)
and so on.
This will translate
target_link_libraries( native-lib
blas
lapack
)
To
clang++ -o libnative-lib.so … libblas.a libnlapack.a libblas.a
Android NDK/JNI -- shared library incompatible with armelf_linux_eabi
The linker error suggests that you are building myproject
for a different ABI than the one that libmylib.so
was built for.
You can tell Gradle to only build your native code for one or more specific ABI(s) by adding an ABI filter:
android {
defaultConfig {
ndk {
abiFilters 'arm64-v8a'
}
}
... other stuff ...
}
Related Topics
How to Open a Fragment on Button Click from a Fragment in Android
How to Get Profile Like Gender from Google Signin in Android
Which Can Replace Capturepicture Function
How to Show Toast in Asynctask in Doinbackground
How to Extract Code of .Apk File Which Is Not Working
When to Request Permissions with Facebook's New Android Sdk 3.0
Adding Expandablelistview to Navigationview
How to Add an Image File into JSON Object
Proguard Ignores Config File of Library
Android Webview - Intercept Clicks
How to Read CPU Frequency on Android Device
Listen to Own Application Uninstall Event on Android
Keyboard Not Shown When I Click on Edittextview in Android
Are Parameters in Strings.Xml Possible