Weird JNI/NDK behavior in eclipse 3.8 - android-ndk

I am unable to use .c files in my NDK projects within eclipse 3.8. Consider the following code:
#include <jni.h>
JNIEXPORT void JNICALL Java_com_atd_ndkdemo_NDKDemo_charManip(JNIEnv* env, jobject obj, jcharArray chrs)
jchar* cchar0 = GetCharArrayElements(chrs, 0);
jchar* cchar1 = (*env)->GetCharArrayElements(env, chrs, 0);
}
Here is my Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := NDKDemo
LOCAL_SRC_FILES := NDKDemo.c
include $(BUILD_SHARED_LIBRARY)
cchar0 doesn't complain until I compile, then I get a method undefined
cchar1 complains before I compile, but is able to compile (if i omit cchar0). I get a method undefined or not part of struct or something similar.
This has me baffled. I have completely reinstalled eclipse/jni/ndk plugin and still same issue. There is a little bug icon next to cchar1 on the left where I set breakpoints if that helps. Also, I have not modified jni.h or any other files. It is important that I leave my file as .c.
edit
Method 'GetCharArrayElements' could not be resolved
Screenshot: http://i.imgur.com/SMacpqy.png
Screenshot to build success: http://i.imgur.com/rcs9Qv7.png

Related

Integrating duktape with android ndk

I'm trying to integrate duktape with android jni. My jni's android.mk is pretty standard:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mynativelib
LOCAL_SRC_FILES := mynativelib.cpp ductape.c
include $(BUILD_SHARED_LIBRARY)
When I try ty compile my native project I get this error:
In file included from jni/duktape.h:174:0,
from jni/mynativelib.cpp:3:
jni/duk_config.h:840:43: fatal error: exception: No such file or directory
#include <exception> /* std::exception */
Error is referring to these lines in duk_config.h
#if defined(DUK_F_CPP)
#include <exception> /* std::exception */
#endif
So should I use configure.py with some specific flags or fix android.mk...?
Seems like writing a question helps brain to come up with an answer. As a background I'm investigating usage of same script in several platforms and I noticed that exception.h is included in windows platform and therefore I believe it is good to keep similar approach on android also. I added these flags to application.mk and it seems to work.
APP_STL := gnustl_static
APP_CPPFLAGS := -fexceptions

Google Project Tango NDK undefined reference on functions

I am getting a compile error:
undefined reference to 'TangoService_getConfig' (MoreTeapotsNativeActivity.cpp)
ld returned 1 exit status (collect2.exe)
I am working with the tango sdk TangoSDK_Ikariotikos_C.zip in Visual Studio 2015 using VisualGDB. I have also replicated the error in Android Studio so it isn't IDE specific.
I have started with an NDK sample project to test a native activity deploys correctly and reduce complexity whilst troubleshooting. I have used VisualGDB MoreTeaPotsNativeActivity but any will do. The app compiles and runs on our ASUS Zenfone AR. Once I include tango_client_api.h and add the following code, I get the compile error:
TangoCoordinateFramePair* Tango_FramePair;
Tango_FramePair = new TangoCoordinateFramePair();
Tango_FramePair->base = TANGO_COORDINATE_FRAME_START_OF_SERVICE;
Tango_FramePair->target = TANGO_COORDINATE_FRAME_DEVICE;
TangoErrorType retval;
// Connect to tango service.
TangoConfig tango_config;
tango_config = TangoService_getConfig(TANGO_CONFIG_DEFAULT);
The Tango header file has an extern "C" wrapper for the C functions and the .o shows them demangled so I can't see why it is failing.
If I comment out...
//tango_config = TangoService_getConfig(TANGO_CONFIG_DEFAULT);
...it compiles and the enums show as locals in the debug so it seems to be a problem with functions: see image of locals here
I may be missing something glaringly obvious because android is fairly new to me. Perhaps someone can test the tangoSDK library with the same code block and spot the issue. It is frustrating that I cannot even link a library. I may be missing something simple but to me it is not obvious.
Any help will be greatly appreciated.
I contacted Sysprogs Support who gave me a link:
PREBUILT_SHARED_LIBRARY syntax
I hadn't realised the library wasn't being copied even though intellisense was reading the header. I needed to include a reference in the make file (android.mk) to copy the library (I copied Tango include and lib folders to the project jni folder):
include $(CLEAR_VARS)
LOCAL_MODULE := tango_client_api
LOCAL_SRC_FILES := ../jni/lib/$(TARGET_ARCH_ABI)/libtango_client_api.so
include $(PREBUILT_SHARED_LIBRARY)
I did the same with an additional block for the support library:
include $(CLEAR_VARS)
LOCAL_MODULE := tango_support_api
LOCAL_SRC_FILES := ../jni/lib/$(TARGET_ARCH_ABI)/libtango_support_api.so
include $(PREBUILT_SHARED_LIBRARY)
The main module just needs this:
LOCAL_SHARED_LIBRARIES := tango_client_api
The whole file looks like this:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := tango_client_api
LOCAL_SRC_FILES := ../jni/lib/$(TARGET_ARCH_ABI)/libtango_client_api.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := tango_support_api
LOCAL_SRC_FILES := ../jni/lib/$(TARGET_ARCH_ABI)/libtango_support_api.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := MoreTeapotsNativeActivity
#VisualGDBAndroid: AutoUpdateSourcesInNextLine
LOCAL_SRC_FILES := gdbserver_launcher.c MoreTeapotsNativeActivity.cpp MoreTeapotsRenderer.cpp
LOCAL_C_INCLUDES := jni/include
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2
LOCAL_STATIC_LIBRARIES := cpufeatures android_native_app_glue ndk_helper
LOCAL_SHARED_LIBRARIES := tango_client_api
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/ndk_helper)
$(call import-module,android/native_app_glue)
$(call import-module,android/cpufeatures)
I didn't get this to work straight away when following the NDK examples but Sysprogs gave me feedback on my mistake which I will include.
I tried to include:
LOCAL_MODULE_FILENAME := tango_client_api
I left off the lib and .so as seemed to be convention. The .so was not necessary but taking lib off was changing the file name which caused a link error. That said, that line was unnecessary in the first place to I removed it. Then it removed the error relating to this. I have yet to see if the library works at runtime because I now get this error:
java.lang.UnsatisfiedLinkError: Unable to load native library "/data/app/com.sample.moreteapots-2/lib/arm64/libMoreTeapotsNativeActivity.so": dlopen failed: library "libbinder.so" not found
But this seems to relate to a problem with Android 7.0 platform 24 and higher where
the system prevents apps from dynamically linking against non-NDK libraries
from /Android/android-sdk/docs/about/versions/nougat/android-7.0-changes.html

Need NDK Help: How to call a C++ function for shared library from another project that uses C++

I am badly pulling my hair as not able to figure out (even though searched a lot on google). Please help
Situation:
I have a shared library. Let's say foo.so (Code completely in C++)
Now in a new project, I want to use this shared library foo.so
The new project code is also in C++. Let's say new project name is fooMate.
I want to call the functions of functions or to use classes of foo in fooMate project cpp files without including the actual source code of foo project (i.e. by just using the foo.so file)
Question:
How can we achieve this?
For Example:
class foo
{
const char* giveMeAString();
}
#include “foo.h”
const char* foo::giveMeAString()
{
return “Hello World!”;
}
Now I have compiled foo class successfully in shared library called: foo.so
Now suppose I am writing another project which is also having some CPP code. But this new CPP code wants to reuse the static library.
// Declaration
class fooMate
{
void printDemo();
}
// Implementation
#include “fooMate.h”
#include “foo.h”
void fooMate::printDemo()
{
foo *testFoo = new foo();
cout<<giveMeAString();
}
How can I achieve this by using foo.so file instead of using actual source code of foo.cpp
Here is the Android.mk file that I am using
#Adding foo.so file in project.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := foo-lib-module
LOCAL_SRC_FILES := foo-lib.so
LOCAL_EXPORT_C_INCLUDES := include
include $(PREBUILT_SHARED_LIBRARY)
#New Project and Source code
include $(CLEAR_VARS)
LOCAL_MODULE := foomate-module
LOCAL_MODULE_FILENAME := foomate-lib
LOCAL_SRC_FILES := fooMate.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/Classes/include
include $(BUILD_SHARED_LIBRARY)

Android NDK - problem linking an external library (can't found it)

I am working with Android NDK r6b under cygwin (the system is updated correctly). I am modifying the hello-jni sample in order to learn working with NDK. Since i have a library written in C++ that i wish to use in the hello-jni (actually, i have created a prj called helloworld with a single .cpp file called ndkfoo.cpp) sample, i created a new Android project in Eclipse (updated for Android), added a jni directory, added a Android.mk and Application.mk files, edited them in order to compile the .cpp. At the end of the compilation, i obtain a .so file.
Now, in the helloworld Android.mk, i need to make some edits in order to tell the linker to include that library. Suppose the library file is libmylib.so, i have the following android.mk script:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ndkfoo
LOCAL_SRC_FILES := ndkfoo.cpp
LOCAL_C_INCLUDES += $(LOCAL_PATH)/mylib
LOCAL_LDLIBS += -L$(LOCAL_PATH)/../../mylib/libs/armeabi/ -lmylib
include $(BUILD_SHARED_LIBRARY)
My directories are organized in the following way:
d:/android/android-ndk-r6b => android ndk root
d:/android/workspace/helloworld => helloworld project
d:/android/workspace/mylib => mylib project library
(therefore, the path to libmylib.so is: d:/android/workspace/mylib/libs/armeabi).
Unfortunately, this doesn't seems to work. If i remove every reference to mylib from ndkfoo.cpp, it compiles and run even on my phone. If i do not remove references to mylib, it compiles but doens't link: i obtain the following result:
D:/android/android-ndk-r6b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windo
ws/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/
bin/ld.exe: cannot find -lmylib
Ps.
I forgot to mention that i run ndk-buld under the jni directory of the helloworld project.
Pss.
I have found a lot of similar questions over the internet. I have always worked with Visual C/C++ IDE, so i am really new to GCC, makefiles and so on...
The message
D:/android/android-ndk-r6b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windo ws/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/ bin/ld.exe: cannot find -lmylib
is indicating you that the linker is not finding your library, this should come from a problem in the LD_LIBS' path.
I think that my-dir macro does not include devices' unit identifier so, your LOCAL_PATH variable should miss the D: and, I think, won't work with cygwin. I'm a Linux user and I'm not 100% sure but, if you replace
LOCAL_PATH := $(call my-dir)
by
LOCAL_PATH := D:$(call my-dir)
it should work. On the other hand you can always set the relative path by setting:
LOCAL_LDLIBS += -L$../../mylib/libs/armeabi/ -lmylib

Trouble w/ std::string when building C++ code in ndk environment

I'm working on some code cuz I was asked to devlep c++ code about core part of a program.
But, it's my first time to use ndk so, I had some troubles and resolved that.
However, too difficult problem is coming to me. I had building my c++ code w/ ndk but,
it said,
.h:3:20: error: string: No such file or directory
.h:5: error: 'std::string' has not been declared
and any other errors about that.
Below is my 'Android.mk' file I wrote:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := clibs
LOCAL_SRC_FILES := sqlite3.c
LOCAL_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_DEFAULT_CPP_EXTENSION := cpp
LOCAL_MODULE := mytweetlib
LOCAL_STATIC_LIBRARIES := clibs
LOCAL_SRC_FILES := Friend.cpp SQLiteDB.cpp Cursor.cpp DB4Friends.cpp ResultParser.cpp MyTweet.cpp Stub.cpp
include $(BUILD_SHARED_LIBRARY)
I tried to link the .c file(sqlite3.c) Making static library file w/ the other file(to be built to shared library).
Is there anyone knows about this? Even if it's just very little clue, plz give me that.
(I haven't been resolving this problem)
It looks like the NDK isn't being told to use stl port.
Try adding an Application.mk file containing APP_STL. This adds the stlport headers to the include path, and links against the libraries.
APP_STL := stlport_static
I would like to add further to Piklor answer.
Do not confuse with "Android.mk" file with "Application.mk" , in your jni folder.
Also your include should include string not string.h

Resources