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

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.

Related

Deploying SQLite database with Delphi application on Android

I'm having some trouble with adding SQLite database into my Android application written in Delphi. First, I have added the database file into the project manager and in deployment manager changed its Remote Path to .\assets\internal\. Then I have added the following code into FDConnection BeforeConnect event. The code is:
begin
{$IFDEF ANDROID}
MissiledbConnection.Params.Values['ColumnMetadataSupported'] := 'False';
MissiledbConnection.Params.Values['Database'] :=
TPath.Combine(TPath.GetDocumentsPath, 'MissileDB.db');
{$ENDIF}
end;
Despite that, I'm still getting this error while trying to compile Android version of my application:
[FireDAC][Stan][Def]-254. Definition [MissileDB.db] is not found in []
When I compile my application under Windows, everything works perfectly fine. I honestly have no idea what I'm doing wrong, since every tutorial I've found only mentions the Deployment manager and the event code, which I implemented as I shown.
Thank you in advance for your help.
I applied to "TPath.GetHomePath" and the application started. Resource 'assets/internal' places the database in this directory by default. It is inaccessible from the outside. How to put deploy to a different but public or shared directory, unfortunately, I do not know.
regards AK

Custom included extras Android (AOSP) Compilation

For reasons, I want to compile the AOSP 4.3.3 tree with the 'user' (aosp_deb-user) build (and not the user-debug / eng builds).
However I would like to specify that I:
would like the su package included (system/extras)
possibly (but less importantly) remove some things I do not need in my testing (therefore speed compilation up) - such as chromium app / camera app / whatever.
Could anyone let me know how to do this?
I already attempted changing the build tag in the su 'Android.mk' to user (which was the old way of doing it) - but it now gives me an error stating I must request in my product packages, however i am unsure where this is.
thank you,
It's (mainly) the PRODUCT_PACKAGES variable that controls which modules are installed. That variable is set in the product makefiles, which form hierarchies of makefiles. The leaf file for a concrete product is usually device/vendorname/productname/productname.mk or similar, in your case device/asus/deb/aosp_deb.mk. In that file you'll find a couple of inclusions:
$(call inherit-product, device/asus/deb/device.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base.mk)
If you following the trail of inherit-product breadcrumbs you'll eventually encounter all PRODUCT_PACKAGES assignments, at least one of which will list the modules that you want to exclude. (The SRC_TARGET_DIR variable in the example above points to the build/target directory.)

How to implement mbtowc for android? (or, ideally, how not to?)

I am attempting to build an Android app that makes use of boost serialization. I have built the library against NDK r8d using arm 4.7's g++. When I go to compile my native code into a library using ndk-build, however, I get "undefined reference to 'mbtowc'" and "undefined reference to 'wctomb'" when the compiler attempts to link some code from Archive headers in boost.
I cannot seem to get a clear answer as to whether the NDK supports these functions.
Although it implements the functions, the CrystaX NDK is not an option as it has known crashes when using it with Boost, according to the Boost mailing list.
So, if the NDK does implement these functions somehow, why is NDK-build unable to link against them? I can find reference to them in cstdlib within the NDK, and I believe there may be a flag I need to set, but I'm not sure how or where to do so.
If there is no implementation of them, does anyone have any advice on how I can write them myself? I know roughly what mbtowc and its complement are supposed to do, but without much experience writing low-level C, and without much knowledge of Android / ARM architecture, I could really use some advice on doing so.
#ifdef ANDROID
int wctomb(char *s, wchar_t wc) { return wcrtomb(s,wc,NULL); }
int mbtowc(wchar_t *pwc, const char *s, size_t n) { return mbrtowc(pwc, s, n, NULL); }
#endif
Findings! Yes, boost has options to build it without requiring wchar support by adding preprocessor definitions to the boost build scripts. Boost still crashes when built using them at the line of code where I attempt to serialize an object to file. (the crash is a generic segfault at 0x00000000, and I was unable to gain any useful information).
So, I haven't bothered writing wctomb or its inverse. I shouldn't need to, is the answer to my question, although in the end the answer to the question doesn't matter.
To further clarify: don't bother doing what I've been trying to do. If you have been using Boost's serialization library and want your code to run on android ndk r8d or earlier, just give up. Write a serializer yourself, because there is no useful information to be found on how to make Serialization work. Hopefully a future release of the ndk fixes this problem, but for now I have no choice but to just rewrite everything.
I had the same problem. I was creating an android port for code that uses boost::serialization.
My code failed to compile because of missing implementation of mbtowc / wctomb (mb: multi-byte (char), wc: (wide-char)'
Implementation of these functions will probably be tricky cause as far as I know the wide-char for android is a single byte char instead of a true wide character..
However when I compiled boost with -DBOOST_NO_STD_WSTRING the link errors disappeared and I could use boost::archive::text_iarchive & boost::archive::text_oarchive on android.
I am now serializing STL containers of numerics and std::strings without a problem.
I compiled boost for android following the advice on this link: http://www.codexperiments.com/android/2011/05/tips-tricks-building-boost-with-ndk-r5/
I am using boost-1.55_0 and NDK r9c.
I added the following <compileflags>-DBOOST_NO_STD_WSTRING to the build command so it would build serialization library without wide character support.

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.

Problem using OpenCV2.3.1 with Android Native Activity

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

Categories

Resources