java.lang.UnsatisfiedLinkError: dlopen failed: can

2020-07-20 05:03发布

问题:

I am new to NDK. I am trying to create an app that can capture packets. I have compiled libpcap from https://github.com/the-tcpdump-group/libpcap

Now when I try to run the application on an android tablet, it gives the following error

07-24 02:29:50.627: E/AndroidRuntime(2014): FATAL EXCEPTION: main
07-24 02:29:50.627: E/AndroidRuntime(2014): Process: com.example.lpcap, PID: 2014
07-24 02:29:50.627: E/AndroidRuntime(2014): java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "cmsg_nxthdr" referenced by "libpcap.so"...
07-24 02:29:50.627: E/AndroidRuntime(2014):     at java.lang.Runtime.loadLibrary(Runtime.java:364)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at java.lang.System.loadLibrary(System.java:526)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at com.example.lpcap.MainActivity.<clinit>(MainActivity.java:37)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at java.lang.Class.newInstanceImpl(Native Method)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at java.lang.Class.newInstance(Class.java:1208)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2112)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at android.app.ActivityThread.access$800(ActivityThread.java:135)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at android.os.Handler.dispatchMessage(Handler.java:102)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at android.os.Looper.loop(Looper.java:136)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at android.app.ActivityThread.main(ActivityThread.java:5017)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at java.lang.reflect.Method.invokeNative(Native Method)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at java.lang.reflect.Method.invoke(Method.java:515)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
07-24 02:29:50.627: E/AndroidRuntime(2014):     at dalvik.system.NativeStart.main(Native Method)

socket.h in ndk has this symbol. I am not sure if it is getting compiled. I have to manually add it, how should I go about it? Following is the Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

libpcap_PSRC =  pcap-linux.c pcap-usb-linux.c  pcap-can-linux.c pcap-netfilter-linux.c  
libpcap_FSRC =  fad-gifc.c
libpcap_CSRC =  pcap.c inet.c gencode.c optimize.c nametoaddr.c etherent.c \
    savefile.c sf-pcap.c sf-pcap-ng.c pcap-common.c \
    bpf_image.c bpf_dump.c
libpcap_GENSRC = scanner.c grammar.c bpf/net/bpf_filter.c version.c lpcap.c

libpcap_SRC =   $(libpcap_PSRC) $(libpcap_FSRC) $(libpcap_CSRC) $(libpcap_GENSRC)
LOCAL_SRC_FILES:=\
    $(libpcap_SRC)
LOCAL_SHARED_LIBRARIES :=  libc cutils
LOCAL_CFLAGS:=-O2 -g
LOCAL_CFLAGS+= -DSYS_ANDROID=1 -Dyylval=pcap_lval -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -Dlinux -D__GLIBC__
#-D_GNU_SOURCE
LOCAL_LDLIBS := -ldl -lc 
LOCAL_MODULE:= libpcap
include $(BUILD_SHARED_LIBRARY)

I am loading this in the java file using

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

I haven't called any method. I just want it to be able to load the library without problems. Please help me solve this.

回答1:

Move your precompiled libpcap to the JNI folder. If you are targetting multiple architectures you need to create multiple folders within your JNI corresponding to each architecture(armeabi,x86 etc) and place the .so files accordingly. Modify your manifest file like below to include your prebuilt shared library

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libpcap
LOCAL_SRC_FILES := libpcap.so
include $(PREBUILT_SHARED_LIBRARY)


include $(CLEAR_VARS)
LOCAL_MODULE    := projectname
LOCAL_SRC_FILES := projectname.cpp
include $(BUILD_SHARED_LIBRARY)

projectname corresponds to the module of libpcap and projectname.cpp corresponds to the actual source file