2011-06-08 75 views
7

我使用bambuser的文件为android编译FFMPEG。编译运行良好。没有错误。 我也确保在build.sh中更改包名。但是,一旦我尝试链接到这些文件,手机就会抛出一个UnsatisfiedLinkError。这是Androkd.mk文件:UnsatisfiedLInkError与NDK链接到FFMPEG

LOCAL_PATH := $(call my-dir) 

include $(CLEAR_VARS) 
MY_LIB_PATH := ffmpeg-android/build/ffmpeg/armeabi/lib 
LOCAL_MODULE := bambuser-libavcore 
LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavcore.so 
include $(PREBUILT_SHARED_LIBRARY) 

include $(CLEAR_VARS) 
LOCAL_MODULE := bambuser-libavformat 
LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavformat.so 
include $(PREBUILT_SHARED_LIBRARY) 

include $(CLEAR_VARS) 
LOCAL_MODULE := bambuser-libavcodec 
LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavcodec.so 
include $(PREBUILT_SHARED_LIBRARY) 

include $(CLEAR_VARS) 
LOCAL_MODULE := bambuser-libavdevice 
LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavdevice.so 
include $(PREBUILT_SHARED_LIBRARY) 

include $(CLEAR_VARS) 
LOCAL_MODULE := bambuser-libavfilter 
LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavfilter.so 
include $(PREBUILT_SHARED_LIBRARY) 

include $(CLEAR_VARS) 
LOCAL_MODULE := bambuser-libavutil 
LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavutil.so 
include $(PREBUILT_SHARED_LIBRARY) 

include $(CLEAR_VARS) 
LOCAL_MODULE := bambuser-libswscale 
LOCAL_SRC_FILES := $(MY_LIB_PATH)/libswscale.so 
include $(PREBUILT_SHARED_LIBRARY) 


#local_PATH := $(call my-dir) 

include $(CLEAR_VARS) 

LOCAL_MODULE := libtest_jni 
LOCAL_SRC_FILES := libtest/video.c 

LOCAL_C_INCLUDES := \ 
    $(LOCAL_PATH)/include \ 
     $(LOCAL_PATH)/ffmpeg-android/ffmpeg 
     LOCAL_LDLIBS := -L$(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm/usr/lib -L$(LOCAL_PATH) -L$(LOCAL_PATH)/ffmpeg-android/build/ffmpeg/armeabi/lib/ -lavformat -lavcodec -lavdevice -lavfilter -lavutil -lswscale -llog -lz -lm 
     #dl -lgcc 

     include $(BUILD_SHARED_LIBRARY) 

VIDEO.C是死的简单:

#include <libavcodec/avcodec.h> 
#include <libavformat/avformat.h> 
#include <libswscale/swscale.h> 

#include <jni.h> 
#include <string.h> 
#include <stdio.h> 
#include <android/log.h> 

void Java_com_bukabros_videolivewallpaper_Opengl2Renderer_loadNthFrame3 
     (JNIEnv * env, jobject this, jstring fileName) { 

     jboolean isCopy; 
     const char * szLogThis = (*env)->GetStringUTFChars(env, fileName, &isCopy); 

      __android_log_print(ANDROID_LOG_DEBUG, "NDK: ", "NDK:LC: [%s]", szLogThis); 
      } 

相应的Tne Java代码也很简单:

private native void loadNthFrame3(String fileName); 

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

但我得到这个错误:

E/AndroidRuntime(11489): FATAL EXCEPTION: main 

E/AndroidRuntime(11489): java.lang.ExceptionInInitializerError 

E/AndroidRuntime(11489): at com.bukabros.videolivewallpaper.VideoLiveWallpaper$CubeEngine.<init>(VideoLiveWallpaper.java:147) 

E/AndroidRuntime(11489): at com.bukabros.videolivewallpaper.VideoLiveWallpaper.onCreateEngine(VideoLiveWallpaper.java:120) 

E/AndroidRuntime(11489): at android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper.executeMessage(WallpaperService.java:814) 

E/AndroidRuntime(11489): at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:61) 

E/AndroidRuntime(11489): at android.os.Handler.dispatchMessage(Handler.java:99) 

E/AndroidRuntime(11489): at android.os.Looper.loop(Looper.java:123) 

E/AndroidRuntime(11489): at android.app.ActivityThread.main(ActivityThread.java:4627) 

E/AndroidRuntime(11489): at java.lang.reflect.Method.invokeNative(Native Method) 

E/AndroidRuntime(11489): at java.lang.reflect.Method.invoke(Method.java:521) 

E/AndroidRuntime(11489): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878) 

E/AndroidRuntime(11489): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636) 

E/AndroidRuntime(11489): at dalvik.system.NativeStart.main(Native Method) 

E/AndroidRuntime(11489): Caused by: java.lang.UnsatisfiedLinkError: Library libtest_jni not found 

E/AndroidRuntime(11489): at java.lang.Runtime.loadLibrary(Runtime.java:461) 

E/AndroidRuntime(11489): at java.lang.System.loadLibrary(System.java:557) 

E/AndroidRuntime(11489): at com.bukabros.videolivewallpaper.Opengl2Renderer.<clinit>(Opengl2Renderer.java:389) 

E/AndroidRuntime(11489): ... 12 more 

我试过手动加载g使用Java(使用System.loadLibrary)的预构建共享库(bambuser文件),但它告诉我找不到文件。

如果有帮助,这里的readelf的输出:

0x00000001 (NEEDED)      Shared library: [libc.so] 
    0x00000001 (NEEDED)      Shared library: [libstdc++.so] 
    0x00000001 (NEEDED)      Shared library: [libm.so] 
    0x00000001 (NEEDED)      Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavformat.so] 
    0x00000001 (NEEDED)      Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavcodec.so] 
     0x00000001 (NEEDED)      Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavdevice.so] 
     0x00000001 (NEEDED)      Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavfilter.so] 
     0x00000001 (NEEDED)      Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavutil.so] 
    0x00000001 (NEEDED)      Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libswscale.so] 
     0x00000001 (NEEDED)      Shared library: [liblog.so] 
     0x00000001 (NEEDED)      Shared library: [libz.so] 
     0x00000001 (NEEDED)      Shared library: [libdl.so] 
     0x0000000e (SONAME)      Library soname: [libtest_jni.so] 
      0x00000010 (SYMBOLIC)     0x0 
      0x00000004 (HASH)      0xd4 
      0x00000005 (STRTAB)      0x250 
     0x00000006 (SYMTAB)      0x130 
      0x0000000a (STRSZ)      712 (bytes) 
      0x0000000b (SYMENT)      16 (bytes) 
      0x00000003 (PLTGOT)      0x174c 
      0x00000002 (PLTRELSZ)     32 (bytes) 
       0x00000014 (PLTREL)      REL 
       0x00000017 (JMPREL)      0x55c 
       0x6ffffffe (VERNEED)     0x53c 
      0x6fffffff (VERNEEDNUM)     1 
       0x6ffffff0 (VERSYM)      0x518 
       0x00000000 (NULL)      0x0 

哦,是的。我正在使用ndk r5。

+2

thx发布您的Androkd.mk它非常有用! – shem 2013-02-19 09:44:14

回答

13

看起来我找到了答案。问题是,当你用Java加载库(System.loadLibrary)时,你不能使用“lib”前缀。我还必须手动加载Java中的ffmpeg库。故事的寓意是你应该总是阅读文档,不要放弃:-)这是正确的代码:

static { 
System.loadLibrary("avcore"); 
System.loadLibrary("avformat"); 
System.loadLibrary("avcodec"); 
System.loadLibrary("avdevice"); 
System.loadLibrary("avfilter"); 
System.loadLibrary("avutil"); 
System.loadLibrary("swscale"); 
System.loadLibrary("test_jni"); 
} 
+0

非常有用! 需要通知其他人,为System.loadLibrary(“test_jni”); 你需要检查你的最后LOCAL_MODULE这名字,你将它设置为VIDEO.C 例如 这样LOCAL_MODULE:= libtest_jni LOCAL_SRC_FILES:= libtest/VIDEO.C *** 如果设置像这样像这样LOCAL_MODULE:=视频LOCAL_SRC_FILES:= libtest/video.c则需要使用System.loadLibrary(“video”); – 2012-12-25 05:56:59