Handmade Hero»Forums»Code
The_8th_mage
69 posts / 1 project
Using Dynamic linked libraries in android
I tried to program stuff to android NDK, and i saw that the build process takes forever, or 60 seconds, but creating a .so library(dll for linux) takes less than 10 second, so i wanted to just link the .so to my app.
Using adb, i pushed the .so to my Samsung galaxy S3. I have unrooted android, i can't make the file system RW(?), and so all my efforts got me pushing it into the sdcard, probably an internal one as i have no external one. Trying to link it , it got me no where. link code:
1
void* handle=dlopen("/storage/sdcard0/0/libgame_lib.so",RTLD_NOW);


The net told me to move it to an internal data folder, but i don't have the permissions to do it.
Does anyone has any idea how to do it?
Mārtiņš Možeiko
2561 posts / 2 projects
Using Dynamic linked libraries in android
Edited by Mārtiņš Možeiko on
Yeah loading executable code from sdcard (internal or external) won't work. That's an security issue so Android doesn't allow that.

There are few options you can try to do. First of all you don't need to do full apk build process. You need to run just the ndk-build to get shared library. Then put this library inside apk file (which is just an zip file), run zipalign and do debug code signing. Doing these last 3 steps manually instead of using SDK build tools will be significantly faster.

Another option is to try to put .so file to /data/local (if you are < Android v4) or /data/local/tmp (if you are >= Android v4) location. Typically everybody can write to these locations and dlopen allows to load shared libraries from this place. You might need to do chmod 777 on .so file you put there. It can happen that vendors like Samsung have modified Android and dlopen will still fail. And I believe Android v5 have changed /data/local/tmp - it also doesn't allow dlopen from that location. But writing files to that location (adb push) still works. Then you can do a bit more trickier workaround. First put .so file somewhere (/data/local or sdcard), and then use run-as helper to copy .so file to it's real location. Something like this:
1
adb shell "cat /data/local/tmp/libgame_lib.so | run-as com.your.package.name sh -c 'cat > /data/app/com.your.package.name-1/lib/arm/libgame_lib.so ; chmod 700 /data/app/com.your.package.name-1/lib/arm/libgame_lib.so'"

Just change com.your.package.name to real package name (and "-1" suffix is version number you specified in manifest). It's been a while time since I have done this, so I may remember some thing wrongly. I think your package must have enabled debug attribute (in manifest) for run-as to work.

Another option would be to try to use adb backup command. It can download or upload full backups of applications on device (unless this is disabled in app manifest). You'll need to do backup to get package from device, unpack it (it is zlib compressed tar file), add your new files, pack it back and then restore on device with adb restore command. A bit more work is involved, but still should be faster than full SDK build.

Here's some blog post on both of these methods (run-as and backup): http://blog.shvetsov.com/2013/02/...ndroid-app-data-without-root.html
The_8th_mage
69 posts / 1 project
Using Dynamic linked libraries in android
i put my new so lib in the /lib/armeabi-v7a installed successfully(wasting some time there) and did a
void* handle=dlopen("libgame_lib.so",RTLD_NOW);

the handle still returned null, am i doing something wrong?
The_8th_mage
69 posts / 1 project
Using Dynamic linked libraries in android
everything works now, thanks.
Mārtiņš Možeiko
2561 posts / 2 projects
Using Dynamic linked libraries in android
What was the solution?
The_8th_mage
69 posts / 1 project
Using Dynamic linked libraries in android
I should have dlopen from the data/data/package/lib directory, and that's was not even the hard problem, that was tricking gradle into not caring that my function pointers I got from the dlsym was not defined at build time, which it didn't need to look for in the first place. I solved it by putting the function pointers into a struct, and gradle didn't look for undefined symbols there.
I truly feel android is awful. I feel it's just workarounds piled on workarounds.
Mārtiņš Možeiko
2561 posts / 2 projects
Using Dynamic linked libraries in android
So you can upload individual files to data/data/package/lib folder just fine?

But function pointers and gradle? That doesn't make sense to me. Gradle only deals with building Java code. It doesn't do anything with native code. C/C++ code is built by Android NDK. And if there is some error (symbol not defined) build will fail and you won't get library in output. NDK is using gcc that shows errors just fine. It doesn't build anything if there are errors.
The_8th_mage
69 posts / 1 project
Using Dynamic linked libraries in android
Gradle rubs ndk in his compilendk phase, but he doesn't use the mk files and instead generate them for himself from the parameter in build.gradle file. You can make him not do it by specifying an empty folder for jni file, but i probably did something wrong with the mk files because the app didn't work. So i needed gradle but at the same time i didn't want his stupid tests.
Fortunately, i won at the end,and the build takes about 10 seconds.