Java Question NDK environment

stevel05

Expert
Licensed User
Longtime User
I am working on a library to wrap the SoundTouch native audio tools library, which I currently have working although there is a problem with the library returning incorrect output which may be caused by a problem with my wrapper code (although I can't see it for looking) or the way I've compiled the library.

I thought I'd start by checking my java/eclipse environment is as it should be and I wanted to ask you what environment should be used.

I am currently using Java JRE6 and jdk1.6.0 along with NDK r7b on Win7 and Cygwin.

I am wondering if I should be using NDK6 ? I don't know how the dependencies work between the different elements.

Thanks

Steve
 
Last edited:

stevel05

Expert
Licensed User
Longtime User
I must admit that this is a little vague in documentation on the internet, I was under the impression that I would need to wrap the existing source with c++, which I have done, then added a java wrapper too.

Are you saying that I can call a compiled library without wrapping it in c++? That would be useful, just creating the java wrapper.

Thanks

Steve
 

stevel05

Expert
Licensed User
Longtime User
It's not an android library, it's a general purpose c++ audio processing library. It speeds up & slows down and transposes raw audio tracks.

I have it working and it does what it's supposed to, it's just that there are issues with the quality of the returned audio signal, which I think is down to missing data in the returned stream.

There were a few issues getting it to communicate between Java and C++, and I might have introduced a problem in there. Unfortunately I don't know C++ that well, the last time I used C was 30 + years ago and it's a different beast.

I'll keep looking, and hopefully can find a problem.
 

SigneFurax

Member
Licensed User
Longtime User
Follow on native libraries

Hello all,
As some others on this forum, I’m very keen to use native shared libraries with B4A. In my case, because I’ve loads of scientific functions written in plain C, that have been optimized for speed. Java is nice but just too slow when it comes to serious number crunching: I made a few tests to interface native functions with Java in Eclipse, and found it to be a good compromise before I discovered B4A, which is a treat for people like me, ie not too Java-driven or “object-oriented”. Though it can do much,much more, it seems the perfect solution to provide quick UI to interface with number crunching software, and I rushed the library tutorial, which showed how simple it was to glue B4A with the java world. Kudos to Erel…:sign0098:
My troubles began when trying to write a Java wrapper that could load a toy shared library written in C (libmylib.so) that has a single function that returns a “Hello world” string through JNI interface. When compiled under Eclipse, loaded with a System.LoadLibrary,(“mylib”) from a test Activity, all is well. At install time, the Eclipse made apk create a /data/data/<package name>/lib folder in which the libmylib.so is placed. At run time, the naltive libray is loaded correctly and the test string is returned fine. As I read a post reply from Erel saying that a working Android .so could probably be wrapped in a library, I had to try....
So I designed a B4A library , with basically the same declaration/loading/calling sequence, but I didn’t know how to tell B4A to install automatically the libmylib.so file. B4A creates a /data/data/<B4A package name>/lib folder, but it is empty
So, I added the .so file to the assets folder, and tried to File.Copy it to a sdcard location, while replacing System.LoadLibrary with System.Load () with the chosen path (before Diming my library class instance). B4A logs now finds the .so file, but crashes with a “java.lang.UnsatisfiedLinkError: Cannot load library: load_segments failed to map segment from “ error. It seems it’s a known error when attempting to override default lib folders.
I tried to File.Copy it to /data/data/<B4A package name>/lib folder, but File.copy returned a permission denied error. Before going further, and try to push the file through adb, could anybody please tell me if there is something basically wrong with my approach? I’m a noob in Android & Java, and I ‘m pretty sure I’m not doing this the correct way..
So, has anybody actually managed to interface native code with B4A?:sign0163:
Moreover, If interfacing native file with B4A is possible, could someone please give some links/detais (or a simple example of how to do it ?
If not, I would very much have it in the wish list?
Thanks a lot in advance
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
So, has anybody actually managed to interface native code with B4A?
Yes :)
SQLCipher library for example loads several modules.

The native module should be copied to the internal folder: anywheresoftware.b4a.objects.streams.File.getDirInternal()

Note that you only need to copy the library if it doesn't already exist.
You should then call System.load:
B4X:
System.load(File.Combine(File.getDirInternal(), "libstlport_shared.so"));
 

SigneFurax

Member
Licensed User
Longtime User
Hello Erel,
I wasn't sure of what you meant by copying to : anywheresoftware.b4a.objects.streams.File.getDirIn ternal()... (I'm sorry, but I'm an absolute beginner in Android&Java world!).
I assumed it was the /data/data/<package name>/file aka File.DirInternal folder

So I tried this:
- In my Java wrapper class, I used your syntax: System.load(File.Combine(File.getDirInternal(), "libmylib.so"));
- Before compiling in B4A,I added the .so file to the File directory , so it was packed it in the DirAssets directory
- In B4A at runtime, I copy the .so files from DirAssets to DirInternal before Diming my first wrapper class object (after testing if it isn't already there)

... and it worked (just returning a string, but it works!).
This is just the thing I was waiting for...: B4A as a neat supervisor, and -hopefully- plain old C code for easy reuse of fast maths code.
Once again, thanks a lot, Erel! This is great work.

PS: For the sake of curiosity, I tried to adb-push the so file in the /data/data/<package name>/lib folder, and it worked with the more standard System.LoadLibrary( "mylib"); syntax.
I wonder if manually including the .so file in a new lib/armeabi folder in the B4A apk would have done the trick? (ie creating automatically the /data/data/<package name>/lib folder with the .so file in it, at install time)? I tried, but obviously, the "tampered" B4A apk didn't install, as it seems to require some extra step (alignment? signing?). It's just for my curiosity, as the above method seems OK :)
 
Last edited:
Top