2011-06-08 71 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