Android NDK / JNI UnsatisfiedLinkError使用.So库

时间:2015-12-03 23:53:27

标签: android c android-ndk rtmp

我是Android NDK的新手,我目前正在尝试为Android(以及后来的iOS)构建RTMP C客户端。目前,我遇到了一个问题,一旦我尝试加载我的库,应用程序崩溃了:

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

我得到的例外是

java.lang.UnsatisfiedLinkError: dlopen failed: could not load library "librtmp.so.1" needed by "libtest.so"; caused by library "librtmp.so.1" not found

老实说,我完全迷失了。 ndk-build不会返回任何错误:

[armeabi] Prebuilt       : rtmp.so <= jni/rtmp/
[armeabi] Install        : rtmp.so => libs/armeabi/rtmp.so
[armeabi] Compile thumb  : test <= RTMPClient.c
[armeabi] SharedLibrary  : libtest.so
[armeabi] Install        : libtest.so => libs/armeabi/libtest.so

我尝试通过System.loadLibrary("rtmp")加载rtmp图书馆,但没有骰子。

Android.mk

LOCAL_PATH:= $(call my-dir)
LIBS_PATH := libs/$(TARGET_ARCH_ABI)

include $(CLEAR_VARS)
LOCAL_MODULE := rtmp
LOCAL_SRC_FILES := rtmp/rtmp.so
LOCAL_C_INCLUDES := rtmp/
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := test
LOCAL_SRC_FILES := RTMPClient.c
LOCAL_LDLIBS    := -llog
LOCAL_SHARED_LIBRARIES += rtmp

include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_PLATFORM:=android-19

我的RTMPClient.c使用rtmp中的一些结构和函数,如下所示:

#include <rtmp/rtmp.h>

我不确定librtmp.so.1来自哪里,但我也发现它在我的libtest.so中使用arm-linux-andrioideabi-readelf:

0x00000001 (NEEDED)                     Shared library: [librtmp.so.1]

关于如何解决此问题的任何想法?

编辑:我从here获得了rtmp.so文件。我是从the KODI librtmp update page

寄来的

1 个答案:

答案 0 :(得分:0)

我最终抛弃了我的rtmp.so文件,而是从rtmpdump-android抓取了jni文件。放入这些文件后,将我的android.mk文件更改为:

#include "librtmp/rtmp.h"

将我的RTMPClient.c文件更改为包含#include <rtmp/rtmp.h>而不是"use strict"; // declare global variables for setup page var zIndexCounter; var pos = []; var origin; // perform setup tasks when page first loads function setUpPage() { document.querySelector("nav ul li:first-of-type").addEventListener("click", loadSetup, false); document.querySelector("nav ul li:last-of-type").addEventListener("click", loadDirections, false); var movableItems = document.querySelectorAll("#room div"); zIndexCounter = movableItems.length + 1; for (var i = 0; i < movableItems.length; i++) { movableItems[i].addEventListener("mspointerdown", startDrag, false); movableItems[i].addEventListener("pointerdown", startDrag, false); if (movableItems[i].addEventListener) { movableItems[i].addEventListener("mousedown", startDrag, false); movableItems[i].addEventListener("touchstart", startDrag, false); } else if (movableItems[i].attachEvent) { movableItems[i].attachEvent("onmousedown", startDrag); } } // disable IE10+ interface gestures movableItems[i].style.msTouchAction = "none"; movableItems[i].style.touchAction = "none"; } // configure page to display Setup content function loadSetup() { document.querySelector("nav ul li:first-of-type").className = "current"; document.querySelector("nav ul li:last-of-type").className = ""; document.getElementById("setup").style.display = "block"; document.getElementById("location").style.display = "none"; location.search = ""; } // configure page to display Directions content function loadDirections(string) { document.querySelector("nav ul li:first-of-type").className = ""; document.querySelector("nav ul li:last-of-type").className = "current"; document.getElementById("setup").style.display = "none"; document.getElementById("location").style.display = "block"; } // run setUpPage() function when page finishes loading window.addEventListener("load", setUpPage, false); // add event listeners and move object // when user starts dragging function startDrag(evt) { // set z-index to move selected element on top of others this.style.zIndex = zIndexCounter; // increment z-index counter so next selected element is // on top of others zIndexCounter++; if (evt.type !== "mousedown") { evt.preventDefault(); this.addEventListener("touchmove", moveDrag, false); this.addEventListener("mspointermove", moveDrag, false); this.addEventListener("pointermove", moveDrag, false); this.addEventListener("touchend", removeTouchListener, false); this.addEventListener("mspointerup", removeTouchListener, false); this.addEventListener("pointerup", removeTouchListener, false); } else { this.addEventListener("mousemove", moveDrag, false); this.addEventListener("mouseup", removeDragListener, false); } pos = [this.offsetLeft, this.offsetTop]; origin = getCoords(evt); } function moveDrag(evt) { var currentPos = getCoords(evt); var deltaX = currentPos[0] - origin[0]; var deltaY = currentPos[1] - origin[1]; this.style.left = (pos[0] + deltaX) + "px"; this.style.top = (pos[1] + deltaY) + "px"; } // identify location of object function getCoords(evt) { var coords = []; if (evt.targetTouches && evt.targetTouches.length) { var thisTouch = evt.targetTouches[0]; coords[0] = thisTouch.clientX; coords[1] = thisTouch.clientY; } else { coords[0] = evt.clientX; coords[1] = evt.clientY; return coords; } } // remove mouse event listeners when dragging ends function removeDragListener() { this.removeEventListener("mousemove", moveDrag, false); this.removeEventListener("mouseup", removeDragListener, false); } // remove touch event listeners when dragging ends function removeTouchListener() { this.removeEventListener("touchmove", moveDrag, false); this.removeEventListener("mspointermove", moveDrag, false); this.removeEventListener("pointermove", moveDrag, false); this.removeEventListener("touchend", removeTouchListener, false); this.removeEventListener("mspointerup", removeTouchListener, false); this.removeEventListener("pointerup", removeTouchListener, false); } ,该文件已编译并在我的设备上运行,没有任何问题。