用jni调用库函数时,经常会碰到link的错误,具体出错信息如下:
08-07 01:42:06.490: E/AndroidRuntime(1665): java.lang.UnsatisfiedLinkError: xxxx
核对后发现函数名称并没有错。
这个问题有几种可能,最根本的解决方法是把so的内容dump出来。具体的方法可以参考 http://stackoverflow.com/questions/34732/how-do-i-list-the-symbols-in-a-so-file
我的文件是elf格式,执行如下的命令:
readelf -Ws xxxx.so >> test.log
so这个库导出的函数就在test.log里了,你可以在log找找看,如果没发现你要导出的函数,
大概有两种可能,第一个是JNIEXPORT没起到作用,第二个是你的函数名或者路径由错误。
附上我的test.log
Symbol table '.dynsym' contains 79 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000fa8 0 SECTION LOCAL DEFAULT 7
2: 0000aaa0 0 SECTION LOCAL DEFAULT 15
3: 00002278 36 FUNC GLOBAL DEFAULT 7 ___Unwind_ForcedUnwind
4: 00001c7c 164 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_RaiseException
5: 00000000 0 FUNC GLOBAL DEFAULT UND ioctl
6: 00000fdd 60 FUNC GLOBAL DEFAULT 7 Java_com_android_ralmes_GlobalProcess_read
7: 00001065 56 FUNC GLOBAL DEFAULT 7 Java_com_android_ralmes_GlobalProcess_isGpioTriggerDeviceExist
8: 00001019 76 FUNC GLOBAL DEFAULT 7 Java_com_android_ralmes_GlobalProcess_write
9: 00002134 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Save_VFP
10: 00002254 36 FUNC GLOBAL DEFAULT 7 _Unwind_Resume_or_Rethrow
11: 0000293c 0 NOTYPE GLOBAL DEFAULT ABS __exidx_end
12: 00000000 0 OBJECT GLOBAL DEFAULT UND __stack_chk_guard
13: 000017d4 8 FUNC GLOBAL DEFAULT 7 __aeabi_unwind_cpp_pr0
14: 00002360 44 FUNC GLOBAL DEFAULT 7 _Unwind_GetRegionStart
15: 00002254 36 FUNC GLOBAL DEFAULT 7 ___Unwind_Resume_or_Rethrow
16: 0000aab0 0 NOTYPE GLOBAL DEFAULT ABS _bss_end__
17: 0000229c 36 FUNC GLOBAL DEFAULT 7 _Unwind_Backtrace
18: 00000000 0 NOTYPE WEAK DEFAULT UND __cxa_begin_cleanup
19: 00002118 20 FUNC GLOBAL DEFAULT 7 __restore_core_regs
20: 00002154 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Save_VFP_D_16_to_31
21: 00000000 0 NOTYPE WEAK DEFAULT UND __cxa_call_unexpected
22: 00001304 8 FUNC GLOBAL DEFAULT 7 _Unwind_GetCFA
23: 00000000 0 FUNC GLOBAL DEFAULT UND memcpy
24: 000012a0 76 FUNC GLOBAL DEFAULT 7 _Unwind_VRS_Set
25: 00000000 0 FUNC GLOBAL DEFAULT UND __cxa_finalize
26: 0000a944 0 NOTYPE GLOBAL DEFAULT 12 __FINI_ARRAY__
27: 000011f1 100 FUNC GLOBAL DEFAULT 7 Java_com_android_ralmes_GlobalProcess_openGpioM0
28: 0000aaa0 0 NOTYPE GLOBAL DEFAULT ABS __bss_start__
29: 00001a18 212 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Backtrace
30: 0000aaa0 4 OBJECT GLOBAL DEFAULT 15 __dso_handle
31: 00002144 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Save_VFP_D
32: 00000000 0 FUNC GLOBAL DEFAULT UND __android_log_print
33: 00001dac 876 FUNC GLOBAL DEFAULT 7 _Unwind_VRS_Pop
34: 000017c4 8 FUNC WEAK DEFAULT 7 __aeabi_unwind_cpp_pr2
35: 0000229c 36 FUNC GLOBAL DEFAULT 7 ___Unwind_Backtrace
36: 0000285c 0 NOTYPE GLOBAL DEFAULT ABS __exidx_start
37: 0000220c 36 FUNC GLOBAL DEFAULT 7 ___Unwind_RaiseException
38: 00000000 0 FUNC GLOBAL DEFAULT UND abort
39: 00002230 36 FUNC GLOBAL DEFAULT 7 ___Unwind_Resume
40: 00000000 0 FUNC GLOBAL DEFAULT UND __stack_chk_fail
41: 00000fb9 36 FUNC GLOBAL DEFAULT 7 _Z43Java_com_android_ralems_GlobalProcess_closeP7_JNIEnvP7_jclassi
42: 0000215c 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Restore_WMMXD
43: 00001189 104 FUNC GLOBAL DEFAULT 7 Java_com_android_ralmes_GlobalProcess_closeGpioM0
44: 00000000 0 FUNC GLOBAL DEFAULT UND write
45: 0000212c 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Restore_VFP
46: 00002230 36 FUNC GLOBAL DEFAULT 7 _Unwind_Resume
47: 00001310 32 FUNC GLOBAL DEFAULT 7 _Unwind_DeleteException
48: 0000130c 4 FUNC GLOBAL DEFAULT 7 _Unwind_Complete
49: 0000aab0 0 NOTYPE GLOBAL DEFAULT ABS __bss_end__
50: 0000109d 236 FUNC GLOBAL DEFAULT 7 Java_com_android_ralmes_GlobalProcess_openSerialPort
51: 0000a93c 0 NOTYPE GLOBAL DEFAULT 11 __INIT_ARRAY__
52: 00000000 0 FUNC GLOBAL DEFAULT UND read
53: 0000238c 888 FUNC GLOBAL DEFAULT 7 __gnu_unwind_execute
54: 0000213c 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Restore_VFP_D
55: 00000000 0 NOTYPE WEAK DEFAULT UND __cxa_type_match
56: 00001d40 108 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Resume
57: 0000214c 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Restore_VFP_D_16_to_31
58: 0000220c 36 FUNC GLOBAL DEFAULT 7 _Unwind_RaiseException
59: 0000aaa0 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
60: 0000aab0 0 NOTYPE GLOBAL DEFAULT ABS __end__
61: 00001c08 28 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_ForcedUnwind
62: 00001d20 32 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Resume_or_Rethrow
63: 00000000 0 FUNC WEAK DEFAULT UND __gnu_Unwind_Find_exidx
64: 00002118 20 FUNC GLOBAL DEFAULT 7 restore_core_regs
65: 000021f8 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Save_WMMXC
66: 00002318 8 FUNC GLOBAL DEFAULT 7 _Unwind_GetTextRelBase
67: 00002328 56 FUNC GLOBAL DEFAULT 7 _Unwind_GetLanguageSpecificData
68: 00001254 76 FUNC GLOBAL DEFAULT 7 _Unwind_VRS_Get
69: 000021e4 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Restore_WMMXC
70: 00002704 64 FUNC GLOBAL DEFAULT 7 __gnu_unwind_frame
71: 00002278 36 FUNC GLOBAL DEFAULT 7 _Unwind_ForcedUnwind
72: 0000aaa0 0 NOTYPE GLOBAL DEFAULT ABS _edata
73: 0000aab0 0 NOTYPE GLOBAL DEFAULT ABS _end
74: 000021a0 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Save_WMMXD
75: 000017cc 8 FUNC WEAK DEFAULT 7 __aeabi_unwind_cpp_pr1
76: 00000000 0 FUNC GLOBAL DEFAULT UND open
77: 00002320 8 FUNC GLOBAL DEFAULT 7 _Unwind_GetDataRelBase
78: 00000000 0 FUNC GLOBAL DEFAULT UND close
我要导出一个叫close的函数,但是第41行的内容如下:
41: 00000fb9 36 FUNC GLOBAL DEFAULT 7 _Z43Java_com_android_ralems_GlobalProcess_closeP7_JNIEnvP7_jclassi
可以看到,导出的函数名不规则,而且ralmes错写成了ralems,
发现问题后立刻就解决了。