[WISH] Compiler support for .so library files

walterf25

Expert
Licensed User
Longtime User
@Krammig

I've sent you a PM.

Martin.
Hey guys, I'm trying to wrap a library that requires two .so files, I was wondering if I could get some advice from you guys.

I've tried loading the files by using
B4X:
system.load library("ctrl_gpio")
But this does not seem to work, in my eclipse project I have a folder called lib/armeabi.
I've tried different ways of doing it but none seems to wor .

Any suggestions or advice will be greatly appreciated.

Thanks
Walter
 

warwound

Expert
Licensed User
Longtime User
First thing i'd do is open your library .jar file and check to see that it contains your 'lib' folder.
In Eclipse when you export your library .jar file you need to ensure that the 'lib' folder as well as your 'src' folder is selected otherwise Eclipse will not add the lib folder to the .jar file.

Your .so file must be named: 'libctrl_gpio.so'?

It's best to call the System.loadLibrary method in your class's static constructor:

B4X:
public class Example{

    static{
        System.loadLibrary("ctrl_gpio");
    }

    // rest of class here
}

Finally look in the unfiltered log.
If you see 'unsatisfied link exception' that means the system has been unable to find the .so file.
You have passed the wrong name to loadLibrary or the .so file does not exist in the correct location on the device file system.
 

walterf25

Expert
Licensed User
Longtime User
First thing i'd do is open your library .jar file and check to see that it contains your 'lib' folder.
In Eclipse when you export your library .jar file you need to ensure that the 'lib' folder as well as your 'src' folder is selected otherwise Eclipse will not add the lib folder to the .jar file.

Your .so file must be named: 'libctrl_gpio.so'?

It's best to call the System.loadLibrary method in your class's static constructor:

B4X:
public class Example{

    static{
        System.loadLibrary("ctrl_gpio");
    }

    // rest of class here
}

Finally look in the unfiltered log.
If you see 'unsatisfied link exception' that means the system has been unable to find the .so file.
You have passed the wrong name to loadLibrary or the .so file does not exist in the correct location on the device file system.
Hi warwound, thanks for your reply, yes my file is named libctrl_gpio.so.
this is my class and this is how i'am loading the files too.
B4X:
public class Android_POS extends AbsObjectWrapper<JBInterface>{
   
    String EventName;
    JBInterface printer;
   
    static{
    System.loadLibrary("ctrl_gpio");
    System.loadLibrary("serial_port");
    }
}

i have a folder named "lib" and a sub folder named "armeabi" the .so files are inside the "armeabi" folder, i tried moving the files directly to the lib folder, and renaming the folder to libs among other things, but i still get the "unsatisfied link exception", i'm not sure what;s going on, i've done this with other libraries and i don't remember it being this much of pain.

Any ideas?

Thanks,
Walter
 

warwound

Expert
Licensed User
Longtime User
@walterf25 But have you opened your library .jar file (with say WinRAR or WinZIP) and checked that it contains your 'lib' folder?
 

walterf25

Expert
Licensed User
Longtime User
@walterf25 But have you opened your library .jar file (with say WinRAR or WinZIP) and checked that it contains your 'lib' folder?
Hi Warwound yes of course i've done that already, and yes the jar file contains the lib and armeabi folder along with the two .so library files.

I did some testing yesterday, and i tried loading other .so files, to my surprise the other .so files load just fine and i get no errors, but for some reason this issue only happens with the .so file that I need to load, even more surprising is that I ran the example that the vendor sent me which also contains this libctrl_gpio.so file and the example runs just fine.

So i'm completely confused as to why i'm seeing this issue.

Any ideas?

Thanks,
Walter
 

warwound

Expert
Licensed User
Longtime User
@walterf25

If i was you and i was testing on a rooted device then i'd use a file explorer to browse the device's /data/data/<your-package-name> directory and establish whether or not the .so files exist.
Also open your compiled .apk file and see if you can see the .so files in the .apk file.
 

walterf25

Expert
Licensed User
Longtime User
@walterf25

If i was you and i was testing on a rooted device then i'd use a file explorer to browse the device's /data/data/<your-package-name> directory and establish whether or not the .so files exist.
Also open your compiled .apk file and see if you can see the .so files in the .apk file.

Hi warwound, unfortunately i'm not using a rooted device, so i can't browse for the .so file in the folder path you mentioned!

Thanks,
Walter
 

walterf25

Expert
Licensed User
Longtime User
Also make sure the your are testing on a device that corresponds the the architecture i.e x86/arm/arm-v7/mips.
But definitely check in the apk if it actually gets packaged.
Hi TDS, how can i check if i'm using a device that corresponds to the architecture x86/arm/arm-v7/mips.
I did check and made sure that the .so files are in the apk file as well.

Thanks,
Walter
 

warwound

Expert
Licensed User
Longtime User
@walterf25

Looking on my rooted Moto G (lollipop) at the install folder of a b4a app that uses a library which uses an .so file i see:

/data/data/<my.package.name>/lib/libglues.so

See the .so file is within my app's main folder?
You could, i think, in b4a check if that 'lib' folder exists and if it does get a list of all files within.
(Your b4a app will have permission to access it's own folders).
 

walterf25

Expert
Licensed User
Longtime User
@walterf25

Looking on my rooted Moto G (lollipop) at the install folder of a b4a app that uses a library which uses an .so file i see:

/data/data/<my.package.name>/lib/libglues.so

See the .so file is within my app's main folder?
You could, i think, in b4a check if that 'lib' folder exists and if it does get a list of all files within.
(Your b4a app will have permission to access it's own folders).
I'll try that.

Thanks
Walter
 

walterf25

Expert
Licensed User
Longtime User
@walterf25

Looking on my rooted Moto G (lollipop) at the install folder of a b4a app that uses a library which uses an .so file i see:

/data/data/<my.package.name>/lib/libglues.so

See the .so file is within my app's main folder?
You could, i think, in b4a check if that 'lib' folder exists and if it does get a list of all files within.
(Your b4a app will have permission to access it's own folders).
Hi warwound, I rooted my lg g3 real quick just to be able to browse into the /data/data directory, i was able to do it with DDMS, attached is a screenshot of the directory, as you can see the lib folder is there, but i don't see the armeabi folder, should it be there or not? how do i know if the libctrl_gpio.so file is in the lib folder? i can't seem to open the lib folder. Any thoughts?


UPDATE:
So I checked at the directory again with ADB, and i can now see that the two .so files are in the /data/data/com.genesis.androidpos/lib/ directory

attached is a screenshot of the two files inside the /lib folder.

So, now i know the files are in there, what the hell is going on, why do I get an error when loading the file then?

:mad:


Thanks,
Walter
 

Attachments

  • lib_armeabi.jpg
    lib_armeabi.jpg
    59.3 KB · Views: 345
  • adb_shell.jpg
    adb_shell.jpg
    76.4 KB · Views: 344
Last edited:

JordiCP

Expert
Licensed User
Longtime User
Are you sure that you get the error when loading the file and not later, when calling one of its functions?

Also, you should check that the jar package name and class name is the same as in the working example since it is necessary for the JNI interface
 

walterf25

Expert
Licensed User
Longtime User
Are you sure that you get the error when loading the file and not later, when calling one of its functions?

Also, you should check that the jar package name and class name is the same as in the working example since it is necessary for the JNI interface
Hi JordiCP, that's a great point, i'll have to double check to see if the error is thrown when the file is loaded or when calling a function, however it is hard to tell, because the file gets loaded when calling the initprinter() function, this functions calls the ioCTL class which loads the file.

Can you elaborate a little more on the jar package name and class name being the same as in the working example please?

Thanks,
Walter
 

JordiCP

Expert
Licensed User
Longtime User
I will try to explain the best I can according to what I have tried. Some things may be inaccurate but basically the facts are:

A "libxxxx.so" library file, contains some "exportable" C functions and other which are not.

In order to make these functions exportable, they are declared (in the C or Cpp file) with a special syntax which basically is the package name concatenated with the calling class name and the function name (all this with some special rules such as converting the dots of the package name to '_' and other...).
As this part is already done and is internal to the .so file, the only rules for the calling part are that the package name and the class name are the ones that the internal functions in the library expect.

You can try it easilly. Change them in your project and see if this was the missing piece. Or also change them in the working project and see if it still works :)
 

walterf25

Expert
Licensed User
Longtime User
I will try to explain the best I can according to what I have tried. Some things may be inaccurate but basically the facts are:

A "libxxxx.so" library file, contains some "exportable" C functions and other which are not.

In order to make these functions exportable, they are declared (in the C or Cpp file) with a special syntax which basically is the package name concatenated with the calling class name and the function name (all this with some special rules such as converting the dots of the package name to '_' and other...).
As this part is already done and is internal to the .so file, the only rules for the calling part are that the package name and the class name are the ones that the internal functions in the library expect.

You can try it easilly. Change them in your project and see if this was the missing piece. Or also change them in the working project and see if it still works :)
Hi JordiCP, thanks so much for your advice, it actually worked now, you are right in mentioning i had to use the same package name they use in their example, as soon as i did that the library loaded just fine.

Thanks for your help!
Walter
 

wonder

Expert
Licensed User
Longtime User
Hi guys,

I've been lurking around on this thread and so far I understood that using .so file, is roughly speaking, a way to add C++ code into your project.
If I understood correctly, B4A calls Java which in turn calls C++ code, kind like this: input --> B4A --> Java --> C++ --> Java --> B4A --> output

Am I on the right track?
 

walterf25

Expert
Licensed User
Longtime User
Hi guys,

I've been lurking around on this thread and so far I understood that using .so file, is roughly speaking, a way to add C++ code into your project.
If I understood correctly, B4A calls Java which in turn calls C++ code, kind like this: input --> B4A --> Java --> C++ --> Java --> B4A --> output

Am I on the right track?
Yes, that is the way i interpret it.
 
Top