Problem using OpenCV2.3.1 with Android Native Activity - android

i'm developing a computer vision application for Android.
That work involves getting camera frames as fast as possible, so I'm trying to build a android application directly in c++ using "android_native_app_glue" and "libnative_camera" to get camera frames.
It seems to be incompatible.
I tested out 2 options.
I tried to use OpenCV on the android NDK sample "NativeActivity", just make the few necessary changes (convert sample to c++, modify android.mk y application.mk and including using namespaces and includes) It gives the following error:
sharedLibrary : libnative-activity.so
C:/Development/android-opencv-wsp/samples/native-activity/obj/local/armeabi-v7a/objs/native-activity/main.o: In function ~Mat':
C:\Development\android-opencv-wsp\samples\native-activity/../../OpenCV-2.3.1/share/OpenCV/../../include/opencv2/core/mat.hpp:297: undefined reference tocv::fastFree(void*)'
and so on
I tried to import the necessary libraries to make a native activity on the OpenCV2.3.1 tutorial 3 sample. I simply modified the Android.mk and added:
LOCAL_STATIC_LIBRARIES := android_native_app_glue
Immediately, when I add this line, I get the following error:
SharedLibrary : libnative_sample.so
C:/Development/android-opencv-wsp/samples/tutorial-3-native/obj/local/armeabi-v7a/objs/native_sample/jni_part.o: In function ~Mat':
C:\Development\android-opencv-wsp\samples\tutorial-3-native/../../OpenCV-2.3.1/share/OpenCV/../../include/opencv2/core/mat.hpp:297: undefined reference tocv::fastFree(void*)'
and so on...
Please, has anyone tested a purely native activity with openCV2.3.1 and libnative_camera to get camera frames?
Thanks in advance.

I solved the problem there. It was my fault (as usual xD) the problem was I was writting in my Android.mk this line: LOCAL_STATIC_LIBRARIES := android_native_app_glue, instead of this line: LOCAL_STATIC_LIBRARIES += android_native_app_glue. I needed the "plus" symbol, in order to add the new library and not deleting the previously loaded. Thanks anyway!!
#Adi Shavit - thx

Change LOCAL_STATIC_LIBRARIES := android_native_app_glue to LOCAL_STATIC_LIBRARIES += android_native_app_glue. Note the plus sign. This will add the new library without deleting the previously loaded one. Source: Edanna in the comments

Maybe you should take a look at the V4L interface? You might want to check out this thread: http://comments.gmane.org/gmane.comp.handhelds.android.ndk/2824
If I recall you can read directly from a camera's dev file in OpenCV.
-James

Related

Calling Dalvik Stack from native code

I am using JNI with Android Studio 1.5.1 targeting Android API 18 and my questions are:
Q.1) How can I call Dalvik internal functions from native code?
For example in the Android source code, in the interpreter module, in the stack.cpp, how can I call the function dvmDumpThreadStack(const DebugOutputTarget* target, Thread* thread) from native code?
It seems that I need to include some files and link to some libraries as stated in this answer but I need specific details. Which files do I need to link to and which files do I need to include in my native code to successfully call the dvmDumpThreadStack function for example?
This is the content of the Andorid.md file
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyLibrary
LOCAL_SRC_FILES := MyLibrary.c
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
Q.2) How to define the required arguments with the required values to call Dalvik internal functions? For example, before I call the dvmDumpThreadStack function, how to define target and thread and which values to store in them before I call the function.
Generally speaking, you don't. They're called "internal" functions for a reason.
If you're really determined to do this, you can find the function pointers by using dlsym() to find the address at runtime. You'll need the "mangled" name, which you can get by examining the binary with nm. (This was easier before the code was switched from C to C++ back in 4.1 or thereabouts.) You can get the Thread* the same way the VM does it, by calling one of the dvmGetThread functions in Thread.cpp (dvmGetThreadByHandle, dvmGetThreadByThreadId, dvmGetThreadFromThreadObject), or by calling dvmThreadSelf() if you're interested in the current thread. Pass that to dvmDumpThread(), which will set up the DebugOutputTarget so you don't have to.
You don't need a header file that defines Thread* to pass a Thread* around. Just declare the thread-getter functions as returning void*, and the thread-dump function as accepting a void* argument. If you're worried about type-safety and portability, don't call internal VM functions from an app.
The one time I actually wanted to do this -- debugging something, don't remember what -- I actually added a new extern "C" function to the VM that took no arguments and just dumped the current thread's stack. That made everything much easier.

delphi XE7 firemonkey android shared object / library to be dynamically loaded - template

Is there a template to create a .so file that can be loaded by another delphi ape file - I have tried starting a blank fire monkey project and changing program to library and build it but the .so file that it produces won't load with dlopen within another delphi project. I have read that in other development environments there is a islibrary setting. I guess more to the point is there an example .so library built with fire monkey - I have found the bare bones link without fire monkey but it uses just jni not androidapi.jni - thanks
If you start a blank Firemonkey project and change Unit to Library, you'll get this compiler error:
[DCC Error] myfunnylib.pas(1): E2029 'UNIT' expected but 'LIBRARY' found
Trying to add an existing library project to the project group will separate said project from the rest of the build and assign unique build targets and platforms to it. Which will leave you with options to compile for Windows and OS X.
The only way I've heard of so far is to pre-compile your library with another compiler. FPC has been mentioned elsewhere. I haven't tried that yet but its next on the list.
http://wiki.freepascal.org/Android
Don't get confused by the fact that every Android app is in fact a shared object with the extension .so (for shared object). However, this is not the same thing as a shared library.
Because a library exports its functions while an application does not. To a compiler, that IS quite a difference though you wouldn't see that by looking at the file extension (but its prefix lib instead).
If you restrict your question to XE and Firemonkey, my only suggestion here would be to look into Android services. A bound local service might offer similar capabilities you'd expect from a library:
http://docwiki.embarcadero.com/RADStudio/Seattle/en/Android_Service
It's also important to note that Android N will not allow dynamic linking anymore so many of the methods you'll find elsewhere as a solution won't work.
suat dmk's code example in the answer below, though up-voted, is misleading.
It cannot be compiled for Android or iOS in XE 10.1 or any of its predecessors.
UPDATE:
There's a definite statement from Embarcadero staff regarding this issue.
It took a bit of patience in explaining the question, but the reply is clear enough:
[..] wants Delphi to have a project type of Shared Library(.so),
in this case then he is right, Delphi does not have it right now. [..]
quod erat demonstrandum
Hence there can be no such template. Also answers this question.
the following codes may be useful.
//-- Code for libMylib.so (MyLib.dproj) ---
library MyLib;
// uses SysUtils;
function GetSum(a, b: integer ) : integer; cdecl;
begin
Result := a + b;
end;
exports
GetSum name 'GetSum';
begin
end.
//-- Code for using libMylib.so (TestMyLib.dproj) ---
var
DocDir, LibFN: string;
GetSum: function(a, b: integer ) : integer; cdecl;
hLib: HMODULE;
begin
DocDir := IncludeTrailingPathDelimiter(System.IOUtils.TPath.GetLibrary`enter code here`Path);
LibFN:=DocDir + 'libMyLib.so';
hLib := LoadLibrary(LibFN); //ERROR (Segmentation fault (11))
if hLib<>0 then
begin
GetSum := GetProcAddress(hLib, 'GetSum');//It works
ShowMessage(IntToStr(GetSum(3, 8)));//It works
end;
end;
P.S: you must add compiled libMyLib.so file to Deployment of TestMyLib.dproj.
P.S2: it gives an error while executing "LoadLibrary", but it Works.
I couldn't find a solution. Probably it is related with compiler/linker options of MyLib.dproj. Because when I test another '.so' file which is compiled with C++, no problem occurs while calling LoadLibrary.

Library build error on Android

After more than two days of building errors, I give up...
I followed this good tutorial here: http://www.cryptopp.com/wiki/Android_(Command_Line) .
It compiles, and the "cryptest.exe" passes all tests. So, I guess that the static library "libcryptopp.a" is OK.
So, I move the "libcryptopp.a" and all the headers files in the Android project.
But when it comes to the building step (as often... :-) ), there are compilation errors, like:
.../Classes/libs/android/libcryptopp.a(files.o): in function std::basic_filebuf<char, std::char_traits<char> >::_M_unshift()
[clone .part.40]:/Users/toto/Developer/NDKs/AndroidNDKs/android-ndk-r8e/sources/cxx-stl/stlport/stlport/stl/_fstream.h:322:
error: undefined reference to 'std::_Filebuf_base::_M_write(char*, int)'
and ~50 others ...
"undefined reference to" errors usually mean that a library is not present, but "libcryptopp.a" is correct here. So I expect that something is missing in the "Android.mk":
include $(CLEAR_VARS)
LOCAL_MODULE := cryptopp-prebuilt
LOCAL_SRC_FILES := ...narf/Classes/libs/android/libcryptopp.
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
/*
here are included other library
*/
LOCAL_STATIC_LIBRARIES := cryptopp-prebuilt
include $(BUILD_SHARED_LIBRARY)
After tries with "APP_STL := stlport_static/dynamic", "APP_STL := gnustl_static/dynamic", etc... no more chances.
Being really not a building/compilation expert (even worse on Android), can somebody help me.
Thank you very much!
Ok. It is working now!
So the linking of "libcryptopp.a" is not working on my Android project with "stlport" but only with "gnustl_static". Perhaps because of others include like "cocosd2-x".
So following the tuto "http://www.cryptopp.com/wiki/Android_(Command_Line)" you must change the script "setenv-android.sh" to have a result like this:
ANDROID_STL_INC: /Users/toto/Developer/NDKs/AndroidNDKs/android-ndk-r8e/sources/cxx-stl/gnu-libstdc++/4.6/include/
ANDROID_STL_LIB: /Users/toto/Developer/NDKs/AndroidNDKs/android-ndk-r8e/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi/libgnustl_static.a
and also move the files (just for the compilation)
/Users/toto/Developer/NDKs/AndroidNDKs/android-ndk-r8e/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi/include/bits
in
/Users/toto/Developer/NDKs/AndroidNDKs/android-ndk-r8e/sources/cxx-stl/gnu-libstdc++/4.6/include/bits
otherwise there are compilation problems...
Ouf!
I think there are a couple problems with your answer.
First, when multiple libraries use the standard runtimes, you must use the shared object version and not the static version. That's covered in ANDROID_NDK_ROOT/docs/CPLUSPLUS-SUPPORT.html.
Second, you probably have a problem with library load order. Static linking makes it go away because references to std::_Filebuf_base::_M_write(char*, int) (and friends) are resolved at compile time, and not link/load time. To fix this, you must load libstlport_shared.so (or libgnustl_shared.so) first, and then load libcryptopp.so second.
If you load libcryptopp.so first, then there is no runtime loaded into the process to resolve std::_Filebuf_base::_M_write(char*, int) (and friends). That's covered under the wiki page with the LD_PRELOAD tricks.
To fix it in Android Java, you would perform the following. See Is -rpath working? for details.
static {
System.loadLibrary("stlport_shared");
System.loadLibrary("cryptopp");
}
The Crypto+++ Andrid wiki page has been updated: http://www.cryptopp.com/wiki/Android_(ommand_Line)#Android_Activity.

Library not found (but found in another activity) using OpenCV and Android NDK

I have went through a myriad of resources (including, but not limited to, OpenCV4Android's Google group, StackOverflow and OpenCV's answers page trying to resolve this, reaching a point where suggestions become redundant. The problem may be more or less similar to a previous (yet to be resolved) question of mine, but a different situation and thus perhaps a different source of error.
I have added an Android Activity to a package containing a successfully-running app (OpenCV's tutorial 3 sample demonstrating ndk use). The activity uses OpenCV's java API, but there is a call to System.loadLibrary("nativefile"); where nativefile represents a native library. The block where the loadLibrary is called is mentioned below; it is in the onManagerConnected() method. At the loadLibrary line, Logcat emits:
02-17 19:27:39.239: E/AndroidRuntime(10872): FATAL EXCEPTION: main
02-17 19:27:39.239: E/AndroidRuntime(10872): java.lang.UnsatisfiedLinkError: Library nativefile not found
02-17 19:27:39.239: E/AndroidRuntime(10872): at java.lang.Runtime.loadLibrary(Runtime.java:461)
02-17 19:27:39.239: E/AndroidRuntime(10872): at java.lang.System.loadLibrary(System.java:557)
Such error indeed did occur multiple times in other questions; and I have tried the suggestions I came across. However, there is a noteworthy observation to this problem; the app that successfully runs (the OpenCV sample) calls the same library through System.loadLibrary("nativefile");.
The code is rather long and thus not helpful to place in the question. However below summarises what I presume are key elements regarding the problem, it also summarises some of the previous answers related to the matter.
The .cpp file called has the correct method name, where I verify that it includes the package name and the class name, as well as the method name, in a pattern similar to: Java_packageNameSeperatedWithUnderScores_callingClassName_methodName. Morever; the code is surrounded within an extern "C" block, as with other OpenCV sample cpp files for native development.
The Android manifest is updated to learn that it launches the activity in question.
Below is the Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include ../../sdk/native/jni/OpenCV.mk
LOCAL_MODULE := nativefile
LOCAL_SRC_FILES := nativefile.cpp
LOCAL_LDLIBS += -llog -ldl
include $(BUILD_SHARED_LIBRARY)
Below is the Application.mk file
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := all
I have tried replacing all in the APP_ABI line with armeabi and also again tried with armeabi-v7a, no different results however.
I've also verified, as suggested in a comment here, that the apk (after being extracted) contains the needed .so file in lib folder under the various architecture type folders.
Below is the BaseLoaderCallBack instantiation block, not much unlike that in the OpenCV sample, however I do not call the OpenCV camera, since the app performs image processing on images read from the SD card.
BaseLoaderCallback loader = new BaseLoaderCallback(this){
public void onManagerConnected(int status){
switch(status){
case LoaderCallbackInterface.SUCCESS:{
System.loadLibrary("nativefile"); break; }
default:{
super.onManagerConnected(status); break; }
} } };
Unlike OpenCV's sample however, in the Activity in question the line loader.onManagerConnected(LoaderCallbackInterface.SUCCESS); is added to the onCreate() method, since the method onManagerConnected didn't seem to be called otherwise.
Before every OpenCV block of statements, the condition if (OpenCVLoader.initDebug()) is checked. I've also tried the recommended OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, loader) conditional check, but still no different results.
Also, the ndk-build runs successfully building the .so files for the native library nativefile.
Given that the other activity, within the same package, load the library and utilises it finely (of course after amending the manifest file and cpp method name accordingly), I presume the project properties are correct (such as adding OpenCV library, and necessary environment paths, etc).
I reviewed the OpenCV sample multiple times and followed the same practice with slight variances, as detailed above.
Any ideas what could be the source of the problem?
Thank you for your time.

How to use CallStack (in CallStack.tpp) in a executable on android platform?

A question from https://stackoverflow.com/a/11467040/1442443
my final target is to dump user space stack.
I try to build a cpp file as below to a executable on android platform. Therefore, by calling tryToGetStack(), I can get call stack of my executable in run time.
#include <utils/CallStack.h>
namespace android
{
extern "C" void tryToGetStack()
{
CallStack stack;
stack.update();
stack.dump("");
}
}
and add lib setting to to Android.mak since CallStack.tpp is in libutils
LOCAL_SHARED_LIBRARIES += libutils
but I always get error with message:
error: undefined reference to 'android::CallStack::CallStack()'
error: undefined reference to 'android::CallStack::update(int, int)'
...
It seems the executable resolve the symbols at link time rather than load the .so file in runtime?
Do I missing something or there is some limit in Android build system?
I know it is a simple question, but I really need help...
update1
I try to add the code to another executable. The result is same... Does anyone knows the rule of android build system?
update2
There are some key words in my console "target StaticExecutable: ...", I think is is the answer.
http://en.wikipedia.org/wiki/Static_executable
my final target is to dump user space stack.
after google so many information from internet, I found there are 4 ways:
ptraceļ¼š http://en.wikipedia.org/wiki/Ptrace
It is really hard to use ptrace, and we need to stop the thread before using ptrace to attach
_unwind_backtrace: the way used by CallStack (CallStack class in CallStack.cpp)
example: http://git.stlinux.com/?p=stm/uclibc.git;a=blob;f=libubacktrace/sysdeps/sh/backtrace.c;h=18b91b1bb3fa26344a521927c631553a410fcf56;hb=d6a3d9ece5922a337800a8e2ed4db7e226f9ccb3
It is work with a drawback: if you use it as the thread is processing signal, it would dump signal stack rather than dump thread stack
The same problen: How to get fullstacktrace using _Unwind_Backtrace on SIGSEGV
backtrace: http://www.gnu.org/software/libc/manual/html_node/Backtraces.html
a GNU extension function, not be implemented in Bionic libc used by Android
reference: https://stackoverflow.com/a/8295238/1442443
reference: http://lists.puredata.info/pipermail/pd-list/2012-02/094258.html
a patch to dump user space thread stack: http://www.gossamer-threads.com/lists/linux/kernel/1525096
but only be implemented in X86 architecture... orz
I try to port it to android, no it only shows the first frame of stack since arm does not use frame pointer.
So... 2 is the answer.
However, I wonder if someone can resolve the problem : How to get fullstacktrace using _Unwind_Backtrace on SIGSEGV
update:
if you can use cross compiler to use glic to compile your code, maybe you can use 3. backtrace !
http://communities.mentor.com/community/cs/archives/arm-gnu/msg02514.html
update2
a good article
http://codingrelic.geekhold.com/2009/05/pre-mortem-backtracing.html
Since this is such an important question here is my answer that worked for me. My code is in C so it has to call a C++ function that can access android::CallStack.
stackdump.cpp:
#include < utils/CallStack.h >
extern "C" void dumpCallStack( char *label)
{
android::CallStack cs;
cs.update();
cs.dump(label);
}
my main code (foo.c):
void dumpCallStack(char *label);
...
dumpCallStack(\__FUNCTION__);
I have had the same problem once. And it is hard to interpret.
The syntax is of course correct and reasonable!
I have tried many methods but it did not work.
Finally, I got an idea that, the lib reference "LOCAL_SHARED_LIBRARIES += libutils" should be put into a makefile generating a dynamic library rather than into a makefile generating a static library. This is the final reason.
Reference:
http://yongbingchen.github.io/blog/2013/05/09/dump-stack-in-android-native-c-code/
I also received this error, but I added:
LOCAL_STATIC_LIBRARIES += libutils
before line of LOCAL_MODULE := xxx in vm/Android.m of three targets and added
LOCAL_SHARED_LIBRARIES += libcorkscrew
in vm/Android.mk
and libdex/Android.mk, and same for the dexlist/Android.mk, dexdump/Android.mk
After all these done, it works for me.

Categories

Resources