Java Question Loading .so library files error

walterf25

Expert
Licensed User
Hello All, i'm trying to write a wrapper for a friend and it requires me to load two .so library riles.

I'am using the following;

B4X:
System.loadLibrary("ctrl_gpio")
However when i try the library i get the following error.

** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
java.lang.UnsatisfiedLinkError: JNI_ERR returned from JNI_OnLoad in "/data/app/com.genesis.androidpos-2/lib/arm/libctrl_gpio.so"
at java.lang.Runtime.loadLibrary(Runtime.java:371)
at java.lang.System.loadLibrary(System.java:989)
at com.genesis.androidpos.Android_POS.TurnOnPrinter(Android_POS.java:45)
at com.genesis.androidpos.main._button1_click(main.java:403)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:171)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:77)
at android.view.View.performClick(View.java:4764)
at android.view.View$PerformClick.run(View.java:19844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5299)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
Does anyone know why this is, or how can i fix this issue?

I've also tried copying the .so files to the File.DirDefaultExternal directory, and then load the files like this:
B4X:
System.load(File.Combine(File.getDirDefaultExternal(), "libctrl_gpio.so"));
When i do this i get this other error:

** Activity (main) Create, isFirst = true **


Copying Files from :/storage/emulated/0/Android/data/com.genesis.androidpos/files libctrl_gpio.so
java.lang.UnsatisfiedLinkError: dlopen failed: couldn't map "/storage/emulated/0/Android/data/com.genesis.androidpos/files/libctrl_gpio.so" segment 1: Permission denied
at java.lang.Runtime.load(Runtime.java:331)
at java.lang.System.load(System.java:982)
at com.genesis.androidpos.Android_POS.Initialize(Android_POS.java:37)
at com.genesis.androidpos.main._activity_create(main.java:349)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
at com.genesis.androidpos.main.afterFirstLayout(main.java:100)
at com.genesis.androidpos.main.access$100(main.java:17)
at com.genesis.androidpos.main$WaitForLayout.run(main.java:78)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5299)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
I hope someone can help me figure out this problem, i have done other libraries in the past and I have been able to succesfully load the .so libraries, i'm not sure if this is an issue only related to L version, unfortunately i do not have a device with an older android version so that I can test on, If anyone has any advice or thoughts on this please let me know.

Thanks,
Walter
 

walterf25

Expert
Licensed User

DonManfred

Expert
Licensed User
already tried renaming the folder lib instead of libs.
The folder must be named libs!

But you are referencing to another folder; not the libs folder... To place .so files you need to have
a folder named "additional" with the following subfolders


if you have an armeabi-v7a so file you need to copy it to the responsind folder.
Some libraries have multiple so files. One for the armeabi folder, one for the armeabi-v7a folder, one for mips and one for x86

You can use this folderstructure in every project. If you dont need to include .so files then you can leve the folders empty
 

walterf25

Expert
Licensed User
Hi guys, thanks for your replies, here's a screen of the project's file structure, as you guys can see i have a folder named lib and a subfolder named armeabi, inside the armeabi folder are the two .so files.

@DonManfred which one is it do I have to name the folder lib or libs?

Do i need to add the folder additional?

Thanks again for all your help guys.

Walter
 

Attachments

DonManfred

Expert
Licensed User
Do you compile with Eclipse or with the SLC?

In case that you are using the SLC like me:
I will show you my "This is my Template i use to build a new Wrapper"

Download and extract please

Every time i create a new wrapper i do copy this folder again to my workspace and change the name "_Basis" to the new wrappername.
Lets say i name it "AndroidPos":
A folder structure like this i have in my workspace




The LIBS folder already contains two jars i often use. android-support-v4.jar AND android-support-v7-appcompat.jar
If i dont need them for the new wrapper i delete the jars...
If i need to include more or other jars i place them in this folder.

The folder additional is not used by Eclipse as i dont compile with eclipse; i do with slc
This folder contains a few other folders. They are all empty by default when i start a new wrapper.



If i need to include a .so file i need to put the into the right folder.
Note: some libraries comes with .so files for all of them; some only armeabi-a

Ok. If i have a armeabi-v7/androidpos.so i would place them into the armeabi-v7a folder.
I do the same for all needed .so files.
 

walterf25

Expert
Licensed User
Do you compile with Eclipse or with the SLC?

In case that you are using the SLC like me:
I will show you my "This is my Template i use to build a new Wrapper"

Download and extract please

Every time i create a new wrapper i do copy this folder again to my workspace and change the name "_Basis" to the new wrappername.
Lets say i name it "AndroidPos":
A folder structure like this i have in my workspace




The LIBS folder already contains two jars i often use. android-support-v4.jar AND android-support-v7-appcompat.jar
If i dont need them for the new wrapper i delete the jars...
If i need to include more or other jars i place them in this folder.

The folder additional is not used by Eclipse as i dont compile with eclipse; i do with slc
This folder contains a few other folders. They are all empty by default when i start a new wrapper.



If i need to include a .so file i need to put the into the right folder.
Note: some libraries comes with .so files for all of them; some only armeabi-a

Ok. If i have a armeabi-v7/androidpos.so i would place them into the armeabi-v7a folder.
I do the same for all needed .so files.
I use eclipse to compile the library, i've tried using slc before, but couldn't figure out how to use it as it was giving me some errors. Let me give it a try again.

Thanks,
Walter
 

walterf25

Expert
Licensed User
Do you compile with Eclipse or with the SLC?

In case that you are using the SLC like me:
I will show you my "This is my Template i use to build a new Wrapper"

Download and extract please

Every time i create a new wrapper i do copy this folder again to my workspace and change the name "_Basis" to the new wrappername.
Lets say i name it "AndroidPos":
A folder structure like this i have in my workspace




The LIBS folder already contains two jars i often use. android-support-v4.jar AND android-support-v7-appcompat.jar
If i dont need them for the new wrapper i delete the jars...
If i need to include more or other jars i place them in this folder.

The folder additional is not used by Eclipse as i dont compile with eclipse; i do with slc
This folder contains a few other folders. They are all empty by default when i start a new wrapper.



If i need to include a .so file i need to put the into the right folder.
Note: some libraries comes with .so files for all of them; some only armeabi-a

Ok. If i have a armeabi-v7/androidpos.so i would place them into the armeabi-v7a folder.
I do the same for all needed .so files.
So I just tried using SLC tool, but it gives me all kinds of errors, I think the reason is because this library was done by a Chinese person, and the source file contains many unknown characters, for example this line, i have no idea what the hell that is.
B4X:
if(str.equals("ä¸æ–‡ï¼ˆç¹?/简 体)")){
So the SLC tool complains about this line here is the error i get while trying to compile.

Starting step: Compiling Java code.
javac 1.7.0_51
C:\Users\florew1\workspace\Android_POS\src\com\genesis\androidpos\SerialPortTools.java:271: error: unmappable character for encoding UTF-8
if(str.equals("?????/? ??")){
^
1 error


Error.
When I compile with eclipse, it compiles just fine, but then again i'm having a problem with loading the .so files.

Any other ideas/thoughts?

Thanks,
Walter
 

walterf25

Expert
Licensed User
what happen inside this if-block? Maybe you just need to check for englishnamed values
Don, this is the entire function, i believe is for unicode characters
B4X:
public void write_Unicode(String msg,String str)
    {
        try {
            if(allowToWrite())
            {
                if(msg == null)
                    msg = "";
               
                if(str.equals("ä¸æ–‡ï¼ˆç¹?/简 体)")){
           
                    for(int i=0;i<msg.length();i++){
                        String s = msg.substring(i, i+1);
                       
                        if(!JBInterface.isChinese(s)){
                            byte[] bytes = s.getBytes();
                            byte[] writebytes = {0x00,bytes[0]};
                            mOutputStream.write(writebytes);                                           
                        }else{
                       
                            mOutputStream.write(JBInterface.getStringToHexBytes(s));                                                                                           
                        }
                    }               
                }else if(str.equals("English")){
                    mOutputStream.write(printerENByte(msg));               
                    mOutputStream.flush();
                    Thread.sleep(50);
                }
            }
        } catch (IOException e1) {
            e1.printStackTrace();
       
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
I'm not sure what what's going on there!

Walter
 

MarcoRome

Expert
Licensed User
Do you compile with Eclipse or with the SLC?

In case that you are using the SLC like me:
I will show you my "This is my Template i use to build a new Wrapper"

Download and extract please

Every time i create a new wrapper i do copy this folder again to my workspace and change the name "_Basis" to the new wrappername.
Lets say i name it "AndroidPos":
A folder structure like this i have in my workspace




The LIBS folder already contains two jars i often use. android-support-v4.jar AND android-support-v7-appcompat.jar
If i dont need them for the new wrapper i delete the jars...
If i need to include more or other jars i place them in this folder.

The folder additional is not used by Eclipse as i dont compile with eclipse; i do with slc
This folder contains a few other folders. They are all empty by default when i start a new wrapper.



If i need to include a .so file i need to put the into the right folder.
Note: some libraries comes with .so files for all of them; some only armeabi-a

Ok. If i have a armeabi-v7/androidpos.so i would place them into the armeabi-v7a folder.
I do the same for all needed .so files.
And work without problem :)
 
Top