Using JsonCpp on X-Cross platform library - android

I'm making a library in C++ with OpenCV and JsonCpp towards building a library for Android and iOS.
On testing my library for Android, I'm making the JNI files but when I try to load the library I'm getting
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol
"_ZN4Json6WriterD2Ev" referenced by "libXYZ.so"...
and that's because I think I'm not building my Json library very well.
The library that I use is this one: https://github.com/open-source-parsers/jsoncpp
My Android.mk is:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_CAMERA_MODULES:=off
OPENCV_INSTALL_MODULES:=on
include $(LOCAL_PATH)/jsoncpp/Android.mk
include /Users/localmac/Desktop/AndroidDevelopment/OpenCV-2.4.9-android-sdk/sdk/native/jni/OpenCV.mk
OPENCV_LIB_TYPE:=SHARED
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_C_INCLUDES += /Users/localmac/mylibrary/OpenCVtry/
LOCAL_C_INCLUDES += /Users/localmac/Desktop/RD/OpenCVtry/Libraries/jsoncpp-master/include
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
LOCAL_MODULE := libXYZ
LOCAL_SRC_FILES := androidClass.cpp main.cpp utils.cpp
LOCAL_LDLIBS += -llog -ldl
include $(BUILD_SHARED_LIBRARY)
I have no idea of how to do this.
Thank you in advance.
EDIT it's not the NDK Compiling's fault.
Even if I compile the JsonCpp, I get the
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZN4Json6WriterD2Ev" referenced by "libXYZ.so"...
EDIT My jsoncpp/Android.mk :
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CPP_EXTENSION := .cpp LOCAL_MODULE := libJsoncpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/jsoncpp/include
LOCAL_SRC_FILES := src/lib_json/json_reader.cpp \
src/lib_json/json_value.cpp \
src/lib_json/json_writer.cpp
include $(BUILD_SHARED_LIBRARY)

You're not linking against Jsoncpp in your makefile. You should add the following line:
LOCAL_SHARED_LIBRARIES := libJsoncpp
before the last include $(BUILD_SHARED_LIBRARY).
You must specify module names for this variable (and its sister LOCAL_STATIC_LIBRARIES), that is, what you specified for the LOCAL_MODULE variable.
Also, that spares you from specifiying the includes in the LOCAL_C_INCLUDE variable (as the makefile will include them directly when specifying the library in the variable I mentioned at the top of my post).
EDIT: For the sake of completeness, I'll add that you can specify multiple libraries like that:
LOCAL_SHARED_LIBRARIES = libJsoncpp \
libOpenCV \
...
and the same goes for LOCAL_STATIC_LIBRARIES.

Related

Using OpenCV with NDK in Android app development

I am testing facedetection program at Android with NDK. I followed all discussions here. I copied all OpenCV's library files inside armeabi and armeabi-v7a into my project libs folder. Then my Android.mk is updated as
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_INSTALL_MODULES := on
OPENCV_CAMERA_MODULES := off
OPENCV_LIB_TYPE := STATIC
include C:\adt-bundle-windows-x86\OpenCV-2.4.9-android-sdk\sdk\native\jni\OpenCV.mk
LOCAL_SRC_FILES := DetectionBasedTracker_jni.cpp
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_LDLIBS += -llog -ldl
LOCAL_MODULE := detection_based_tracker
include $(BUILD_SHARED_LIBRARY)
Then I go to command window and type
C:\facedetection\jni\include>javah -classpath ../../bin/classes;C:
\adt-bundle-windows-x86\sdk\platforms\android-18\android.jar -o DetectionBas
edTracker_jni.h org.opencv.samples.facedetect.FdActivity
Error: Class org.opencv.android.CameraBridgeViewBase could not be found.
Then the error is Class org.opencv.android.CameraBridgeViewBase could not be found.
What could be the reason for that error?
Thanks
You are providing wrong \ slash. You need to use this / slash instead.
Please change your below line
include C:\adt-bundle-windows-x86\OpenCV-2.4.9-android-sdk\sdk\native\jni\OpenCV.mk
to
include C:/adt-bundle-windows-x86/OpenCV-2.4.9-android-sdk/sdk/native/jni/OpenCV.mk

Include shared dynamic library in jni ndk build

I am trying to compile a ndk module for my android app with a Shared Library provided with these drivers:
http://www.extendo-printer.de/fileadmin/user_upload/extendo/Drivers/X-56-Hengstler-Extendo-LinuxDrivers-S684018-R2-V1_01-FINAL-2009JUL15.zip
I can compile fine with the defaults (using Hello JNI example). But when I add my code the my C file which references a .so library I need to work with I get compile errors stating it can not find the methods defined in the library. When I try to include it in Android.mk in LOCAL_SRC_FILES i get warnings when it builds (unsupported file extension) but it builds, but than my native method call fails (java.lang linkage error). Is there a proper way to include a .so and than reference it's functions in your native C code?
current Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := x56-jni
LOCAL_LDLIBS := libExoApi.so
LOCAL_SRC_FILES := x56-jni.c
include $(BUILD_SHARED_LIBRARY)
I tried with LOCAL_SHARED_LIBRARIES as well with same build error. I've also tried adding to LOCAL_SRC_FILES as stated above (LOCAL_SRC_FILES := x56-jni.c libExoApi.so) with a "," and as well as \ syntax.
Update
I've updated Android.mk to:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libExoApi
LOCAL_SRC_FILES := libExoApi.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := x56-jni
LOCAL_LDLIBS := libExoApi.so
LOCAL_SRC_FILES := x56-jni.c
LOCAL_SHARED_LIBRARIES := libExoApi
include $(BUILD_SHARED_LIBRARY)
This fails at:
[exec] Unable to recognise the format of the input file `/var/folders/_6/6jjydzjs457fnpsc9_5cgl980000gn/T//michael/usbserial-generated/libs/armeabi/libExoApi.so'

Build shared library linking to other not standard shared libarary

I have some two shared libraries and header for them.
I want to build third shared library using functions from previous two libs.
Have problem with makefile i think. When i try to build receive this:
Android NDK: /cygdrive/d/.../jni/Android.mk: Cannot find module with tag 'shared1' in import path
Android NDK: Are you sure your NDK_MODULE_PATH variable is properly defined ?
Android NDK: The following directories were searched:
Android NDK:
/cygdrive/d/.../jni/Android.mk:36: *** Android NDK: Aborting. . Stop.
structure of my project:
jni/
- myfile.c
- Android.mk
jni/dec/
- lot of header files
jni/enc/
- lot of header files
libs/armeabi/
- shared1.so
- shared2.so
also Android.mk sourse:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/dec \
$(LOCAL_PATH)/enc
LOCAL_SHARED_LIBRARIES := shared1 shared2
LOCAL_MODULE := mylib
LOCAL_SRC_FILES := myfile.c
LOCAL_LDLIBS += -lOpenSLES
LOCAL_LDLIBS += -llog
LOCAL_LDLIBS += -landroid
include $(BUILD_SHARED_LIBRARY)
$(call import-module, shared1)
$(call import-module, shared2)
Take a look to this question: Android JNI APK Packing
You need to give another name for libs/armeabi/ folder to avoid conflicts with NDK build and add the following code before the include $(CLEAR_VARS) statement:
include $(CLEAR_VARS)
LOCAL_MODULE:=shared1
LOCAL_SRC_FILES:=3rdparty_libs/shared1.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:=shared2
LOCAL_SRC_FILES:=3rdparty_libs/shared2.so
include $(PREBUILT_SHARED_LIBRARY)
As I understand it, the correct method is to use ndk-build and not invoking the compiler directly.
In Android.mk you need to specify a module for each static library you want to compile, and then specify that your shared library should use it.
Example of a modified Android.mk file of the hello-jni sample project:
LOCAL_PATH := $(call my-dir)
# Define vars for library that will be build statically.
include $(CLEAR_VARS)
LOCAL_MODULE := <module_name>
LOCAL_C_INCLUDES := <header_files_path>
LOCAL_SRC_FILES := <list_of_src_files>
# Optional compiler flags.
LOCAL_LDLIBS = -lz -lm
LOCAL_CFLAGS = -Wall -pedantic -std=c99 -g
include $(BUILD_STATIC_LIBRARY)
# First lib, which will be built statically.
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_STATIC_LIBRARIES := <module_name>
LOCAL_C_INCLUDES := <header_files_path>
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
If you want control over which modules to compile when you run ndk-build you can create create a Application.mk file (in the same directory as Android.mk) and list all the modules as in the following example:
APP_MODULES := <module_name_1> <module_name_2> ... <module_name_n>
I think it Helps you

Unsatisfied Link Error - Could not find Library

I'm attempting to load the libjnigraphics.so prebuilt library to my project, however when I deploy the application, I am receiving this error:
06-17 22:35:28.741: INFO/dalvikvm(298): Unable to dlopen(/data/data/com.foo/lib/libndkfoo.so): Cannot load library: link_image[1721]: 29 could not load needed library 'libjnigraphics.so' for 'libndkfoo.so' (load_library[1051]: Library 'libjnigraphics.so' not found)
It compiles perfectly, fine.
Here's my Android.mk as well:
LOCAL_PATH := $(call my-dir)
# Add prebuilt libjnigraphics
include $(CLEAR_VARS)
LOCAL_MODULE := libjnigraphics
LOCAL_SRC_FILES := libjnigraphics.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
# Here we give our module name and source file(s)
LOCAL_MODULE := ndkfoo
LOCAL_SRC_FILES := ndkfoo.c
LOCAL_SHARED_LIBRARY := libjnigraphics
#LOCAL_LDLIBS += -libjnigraphics
LOCAL_LDLIBS += -llog
include $(BUILD_SHARED_LIBRARY)
Is there a special place I need to put the libjnigraphics.so? Right now I have it in the jni folder, however I've tried it in multiple other places and it still fails. Any help?
The device has to be running Foyo (Android 2.2, target platform android-8) to be able to use libjnigraphics.so. It doesn't matter what is in your SDK or project directories, this library is part of the device's system libraries.
You can compile your code using the NDK with android-8, but then it will give link-time errors when you side-load the apk and your device happens to be running 2.1 or earlier.
There's this SO question with a workaround, but it shouldn't be relied upon and will crash on some devices. Here's a post on the android-ndk group explaining the issues.
just try these changes:
LOCAL_PATH := $(call my-dir)
# Add prebuilt libjnigraphics
include $(CLEAR_VARS)
LOCAL_MODULE := graphics-prebuilt
LOCAL_SRC_FILES := libjnigraphics.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
# Here we give our module name and source file(s)
LOCAL_MODULE := ndkfoo
LOCAL_SRC_FILES := ndkfoo.c
LOCAL_SHARED_LIBRARY := graphics-prebuilt
LOCAL_LDLIBS += -llog
include $(BUILD_SHARED_LIBRARY)

Add shared lib.so to android project

I have an Android project using some native functions. Native functions are using some functions from external shared library "external_lib.so"
I've added to Android.mk: "-lexternal_lib -L/path/to/external/lib" line and myjni.so have been linked successfully. But during runtime myjni.so loading error occurred. The size of myjni.so reflects that external_lib.so is not included. How to fix the problem?
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myjni
LOCAL_SRC_FILES := myjni.c
LOCAL_LDLIBS := -ldl -llog -lz -lexternal_lib -L/path/to/external/lib
include $(BUILD_SHARED_LIBRARY)
is the .so a third party prebuilt shared library?
if so, in your Android.mk, you need to have:
...
LOCAL_SHARED_LIBRARY := curl
...
LOCAL_LDLIBS += -L$(ANDROID_LIBCURL_LIB_PATH) -lcurl
LOCAL_SHARED_LIBRARIES := curl
include $(BUILD_SHARED_LIBRARY)

Categories

Resources