4 messages in com.googlegroups.android-beginners[android-beginners] Re: Problem loadi...
FromSent OnAttachments
Ashutosh Malviya30 May 2008 02:30 
Digit30 May 2008 07:23 
Ashutosh Malviya01 Jun 2008 20:46 
Digit02 Jun 2008 05:09 
Subject:[android-beginners] Re: Problem loading C++ library in Android
From:Digit (digi@gmail.com)
Date:05/30/2008 07:23:47 AM
List:com.googlegroups.android-beginners

you do realize that your NativeCpp.so doesn't have a "ret_mul" symbol at all, hence the link error ?

On Fri, May 30, 2008 at 11:31 AM, Ashutosh Malviya <iamm@gmail.com> wrote:

Hello All,

I am trying to call an API in a C++ library libNativeCpp.so and Android does not load it. The error is --

DEBUG/dalvikvm(1185): LOADING path /system/lib/libNativeCpp.so 0x4001f6e8 INFO/dalvikvm(1185): Unable to dlopen(/system/lib/libNativeCpp.so): Cannot find library

I have used arm-2008q1/bin/arm-none-linux-gnueabi-gcc, arm-2008q1/bin/arm-none-linux-gnueabi-g++ for compilation.

How I tried to do it, is explained below --

I have gone through the URL http://davanum.wordpress.com/2007/12/09/android-invoke-jni-based-methods-bridging-cc-and-java/and
have been able to run the program successfully.

After this I have made some changes in the source code. 1) I have changed signature of function add() in class NativeAdd. It is now 'public static native long add(int a, int b)'. 2) I have changed function Java_org_apache_NativeAdd_add() in file org_apache_NativeAdd.c. It now looks like --

#include "org_apache_NativeAdd.h"

JNIEXPORT jlong JNICALL Java_org_apache_NativeAdd_add (JNIEnv *env, jclass c, jint a, jint b) { long aa; aa = ret_mul(a, b); // aa = ret_mul_cpp(a, b); return aa; }

The function ret_mul() is written in another file called NativeC.c. Content of file is -- #include <stdio.h> int ret_mul(int a, int b) { return (a * b); }

Now I compile these files and create libraries --

arm-none-linux-gnueabi-gcc -I /usr/java/jdk1.6.0_04/include -I /usr/java/jdk1.6.0_04/include/linux -fpic -c org_apache_NativeAdd.c arm-none-linux-gnueabi-ld -T armelf_linux_eabi.xsc -shared -o libNativeAdd.so org_apache_NativeAdd.o

arm-none-linux-gnueabi-gcc -fpic -c NativeC.c arm-none-linux-gnueabi-ld -T armelf_linux_eabi.xsc -shared -o libNativeC.so NativeC.o

The file armelf_linux_eabi.xsc is modified as per the suggestion on the URL

http://honeypod.blogspot.com/2007/12/shared-library-hello-world-for-android.html.

I pushed the library to android environment -- adb push libNativeAdd.so /system/lib adb push libNativeC.so /system/lib

I have created an android project CallNative1 and in file NativeAdd.java, I am loading libraries as below -- System.loadLibrary("NativeC"); System.loadLibrary("NativeAdd");

When I run the project CallNative1, it prints the result as multiplication of two integers.

Now I write the same ret_mul() function in NativeCpp.cpp. Content of NativeCpp.cpp is --

#include <iostream> int ret_mul_cpp(int a, int b) { return (a * b); }

Compiled it --

arm-none-linux-gnueabi-g++ -fpic -c NativeCpp.cpp arm-none-linux-gnueabi-ld -T armelf_linux_eabi.xsc -shared -o libNativeCpp.so NativeCpp.o

Pushed the library --

adb push libNativeCpp.so /system/lib

Now loading libraries as below --

System.loadLibrary("NativeCpp"); System.loadLibrary("NativeAdd");

When I run CallNative1 again I can see below errors in logcat.

DEBUG/dalvikvm(1185): LOADING path /system/lib/libNativeCpp.so 0x4001f6e8 INFO/dalvikvm(1185): Unable to dlopen(/system/lib/libNativeCpp.so): Cannot find library

Below are the information about symbols in both the libraries --

arm-none-linux-gnueabi-nm libNativeC.so 00000244 a _DYNAMIC 0000029c a _GLOBAL_OFFSET_TABLE_ 000002a8 A __bss_end__ 000002a8 A __bss_start 000002a8 A __bss_start__ 000002a8 D __data_start 000002a8 A __end__ 00000244 A __exidx_end 00000244 A __exidx_start 000002a8 A _bss_end__ 000002a8 A _edata 000002a8 A _end 00000214 T ret_mul

arm-none-linux-gnueabi-nm libNativeCpp.so ========================================= 000007a0 a _DYNAMIC 00000840 a _GLOBAL_OFFSET_TABLE_ 000006ec t _GLOBAL__I__Z11ret_mul_cppii 00000460 T _Z11ret_mul_cppii 00000640 t _Z41__static_initialization_and_destruction_0ii U _ZNKSs4sizeEv U _ZNKSsixEj U _ZNSt8ios_base4InitC1Ev U _ZNSt8ios_base4InitD1Ev 00000490 t _ZSt17__verify_groupingPKcjRKSs 00000708 W _ZSt3minIjERKT_S2_S2_ 00000868 b _ZSt8__ioinit U __aeabi_atexit U __aeabi_unwind_cpp_pr0 U __aeabi_unwind_cpp_pr1 0000086c A __bss_end__ 00000868 A __bss_start 00000868 A __bss_start__ 00000868 B __data_start U __dso_handle 0000086c A __end__ 0000079c A __exidx_end 00000774 A __exidx_start 0000086c A _bss_end__ 00000868 A _edata 0000086c A _end

I have gonn through the discussion at http://groups.google.com/group/android-internals/browse_thread/thread/780ba5316409cf5dand
I also feel that the problem is with unresolved symbols.

I pulled whole /system directory from Android and tried to grep one of the undefined symbols _ZNKSs4sizeEv, in /system but could not find it. But if I grep them in arm-2008q1 directory I find many matches.

grep -r _ZNKSs4sizeEv arm-2008q1/* Binary file arm-2008q1/arm-none-linux-gnueabi/libc/armv4t/usr/lib/libstdc++.so.6 matches Binary file arm-2008q1/arm-none-linux-gnueabi/libc/armv4t/usr/lib/libstdc++.a matches Binary file arm-2008q1/arm-none-linux-gnueabi/libc/armv4t/usr/lib/libstdc++.so.6.0.9 matches Binary file arm-2008q1/arm-none-linux-gnueabi/libc/armv4t/usr/lib/libstdc++.so matches Binary file arm-2008q1/arm-none-linux-gnueabi/libc/thumb2/usr/lib/libstdc++.so.6 matches Binary file arm-2008q1/arm-none-linux-gnueabi/libc/thumb2/usr/lib/libstdc++.a matches Binary file arm-2008q1/arm-none-linux-gnueabi/libc/thumb2/usr/lib/libstdc++.so.6.0.9 matches Binary file arm-2008q1/arm-none-linux-gnueabi/libc/thumb2/usr/lib/libstdc++.so matches Binary file arm-2008q1/arm-none-linux-gnueabi/libc/usr/lib/libstdc++.so.6 matches Binary file arm-2008q1/arm-none-linux-gnueabi/libc/usr/lib/libstdc++.a matches Binary file arm-2008q1/arm-none-linux-gnueabi/libc/usr/lib/libstdc++.so.6.0.9 matches Binary file arm-2008q1/arm-none-linux-gnueabi/libc/usr/lib/libstdc++.so matches

I don't know why these symbols are not there in /system/lib at android. Statically linking a C++ library is not advisable.

Could anyone please suggest me how do I go about it ?

Thanks Ashutosh