在应用程序中使用外部静态库(NDK) [英] Use external static library in application (NDK)

查看:337
本文介绍了在应用程序中使用外部静态库(NDK)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始与NDK工作,我坚持的一个问题。我基本上要使用一个外部静态库(的.so)到我的应用程序。下面是我试过至今。

创建库

1)添加方法与本地关键词的Java类

 公共本地静态无效FibNR();

2)在终端导航到项目文件夹,然后运行以下命令

 的mkdir JNI
    JAVAH -jni -classpath斌/班/ -d JNI / com.example.fibonaccinative.FibLib

3)刷新项目,并添加相应的生成.h文件C文件。

4)创建的文件夹JNI一个Android.mk文件,并添加以下code在它

  LOCAL_PATH:= $(叫我-DIR)
    包括$(CLEAR_VARS)
    OPENCV_LIB_TYPE:= STATIC
    LOCAL_SRC_FILES:= com_example_fibonaccinative_FibLib.c
    LOCAL_MODULE:= com_example_fibonaccinative_FibLib
    包括$(BUILD_SHARED_LIBRARY)

5)使用以下命令构建code

  /开发/ Android的NDK-R9B / NDK的构建所有


上述步骤成功执行,我可以查看C code的结果也。现在,我想创建一个新的应用程序,并使用生成的.so文件(com_example_fibonaccinative_FibLib.so)到它。为此,我做了以下

使用库

后续来自上述步骤1,2和3为新的应用

4)创建的文件夹JNI一个Android.mk文件,并添加以下code在它

  LOCAL_PATH:= $(叫我-DIR)
包括$(CLEAR_VARS)
OPENCV_LIB_TYPE:= STATIC
LOCAL_SRC_FILES:= com_example_usingstaticlibrary_LibraryTest.c
LOCAL_MODULE:= com_example_usingstaticlibrary_LibraryTest
LOCAL_SHARED_LIBRARIES:= libcom_example_fibonaccinative_FibLib.so
LOCAL_LDLIBS:= -L $(SYSROOT)的/ usr -llog
包括$(BUILD_SHARED_LIBRARY)

5)使用以下命令构建code

  /开发/ Android的NDK-R9B / NDK的构建所有


我不知道下一步该怎么做。我觉得我需要调用库函数到com_example_usingstaticlibrary_LibraryTest.c。但是这样做给了我一个错误说


  

com_example_fibonaccinative_FibLib'未申报




编辑1:

1)在项目2(在这里我想用prebuilt共享库(的.so))我复制库到JNI文件夹

2)改变了Android.mk与下面的文本文件。

  LOCAL_PATH:= $(叫我-DIR)
包括$(CLEAR_VARS)
LOCAL_MODULE:= libcom_example_fibonaccinative_FibLib
LOCAL_SRC_FILES:= libcom_example_fibonaccinative_FibLib.so
包括$(preBUILT_SHARED_LIBRARY)包括$(CLEAR_VARS)
LOCAL_MODULE:= com_example_usingstaticlibrary_LibraryTest
LOCAL_SHARED_LIBRARIES:= libcom_example_fibonaccinative_FibLib
LOCAL_SRC_FILES:= com_example_usingstaticlibrary_LibraryTest.c
包括$(BUILD_SHARED_LIBRARY)

3)添加了从旧项目(com_example_fibonaccinative_FibLib.h).h文件到JNI文件夹

4)已变更com_example_usingstaticlibrary_LibraryTest.c的来源,以

 的#includecom_example_usingstaticlibrary_LibraryTest.h
#包括com_example_fibonaccinative_FibLib.hJNIEXPORT jlong​​ JNICALL Java_com_example_usingstaticlibrary_LibraryTest_callLibraryFunction
(JNIEnv的* ENV,JCLASS类){
    Java_com_example_fibonaccinative_FibLib_fibNR(ENV,类500升);
    返回-500l;
}

清洁/建设成果转化为下面的错误

 未定义引用'Java_com_example_fibonaccinative_FibLib_fibNR



编辑2:

参照我已经编辑了Android。 MK如下:

  LOCAL_PATH:= $(叫我-DIR)包括$(CLEAR_VARS)
LOCAL_MODULE:= com_example_fibonaccinative_FibLib
LOCAL_SRC_FILES:= libcom_example_fibonaccinative_FibLib.so
LOCAL_EXPORT_C_INCLUDES:= $(LOCAL_PATH)/包括:
包括$(preBUILT_SHARED_LIBRARY)包括$(CLEAR_VARS)
LOCAL_MODULE:= com_example_usingstaticlibrary_LibraryTest
LOCAL_SRC_FILES:= com_example_usingstaticlibrary_LibraryTest.c
LOCAL_SHARED_LIBRARIES:= com_example_fibonaccinative_FibLib
包括$(BUILD_SHARED_LIBRARY)

NDK的构建命令编译code没有错误。当试图加载库它提供了以下错误

 异常Ljava /朗/的UnsatisfiedLinkError;扔在初始化LCOM /例子/ usingstaticlibrary / LibraryTest

当我删除 LOCAL_SHARED_LIBRARIES:= com_example_fibonaccinative_FibLib 它工作正常,但我不能用prebuilt共享库的任何功能。



修改3:

我尝试了一些更多的东西包括@jcm,但没有工作的建议。现在我的附加源$ C ​​$ C 。它有两个项目(清洗版本,以减少大小)。


  1. FibonacciNative:包含的第一个项目

  2. UsingStaticLibrary:包含第二个项目。我打算用prebuilt的第一个项目的共享库进入第二个。


解决方案

随着你包括libcom_example_fibonaccinative_FibLib.so作为LibraryTest的共享库,在您的Java静态方法,你应该在加载LibraryTest之前加载:

 的System.loadLibrary(com_example_fibonaccinative_FibLib);
的System.loadLibrary(LibraryTest);

更新:

检查你的code后,LibraryTest.java应该是这样的:

 包com.kochartech.usingstaticlibrary;公共类LibraryTest {    公共本地静态长callLibraryFunction();    静态的 {
        的System.loadLibrary(com_kochartech_fibonaccinative_FibLib);
        的System.loadLibrary(com_kochartech_usingstaticlibrary_LibraryTest);
    }}

I have recently started working with NDK and am stuck with a problem. I basically want to use an external static library (.so) into my application. Here's what I've tried till now.

Create a library

1) Add a method in the Java class with native keyword

public native static void FibNR ();

2) In the terminal navigate to the project folder and run the following command

    mkdir jni
    javah -jni -classpath bin/classes/ -d jni/ com.example.fibonaccinative.FibLib

3) Refresh project and add a C file corresponding to the generated H file.

4) Create a Android.mk file in the JNI folder and add the following code in it

LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    OPENCV_LIB_TYPE :=STATIC
    LOCAL_SRC_FILES := com_example_fibonaccinative_FibLib.c
    LOCAL_MODULE := com_example_fibonaccinative_FibLib
    include $(BUILD_SHARED_LIBRARY)

5) Build the code using the following command

/Developer/android-ndk-r9b/ndk-build all


The above steps execute successfully and I'm able to view the results of the c code also. Now I want to create a new application and use the generated .so file (com_example_fibonaccinative_FibLib.so) into it. For this I do the following

Use the library

follow steps 1, 2 and 3 from above for the new application

4) Create a Android.mk file in the JNI folder and add the following code in it

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_LIB_TYPE :=STATIC
LOCAL_SRC_FILES := com_example_usingstaticlibrary_LibraryTest.c
LOCAL_MODULE := com_example_usingstaticlibrary_LibraryTest
LOCAL_SHARED_LIBRARIES :=libcom_example_fibonaccinative_FibLib.so
LOCAL_LDLIBS := -L$(SYSROOT)/usr -llog
include $(BUILD_SHARED_LIBRARY)

5) Build the code using the following command

/Developer/android-ndk-r9b/ndk-build all


I'm not sure what to do next. What I think is I need to call the function of the library into com_example_usingstaticlibrary_LibraryTest.c. But doing so gives me an error saying

'com_example_fibonaccinative_FibLib' undeclared



EDIT 1:

1) In project 2 (where I want to use the Prebuilt Shared Library (.so)) I copied the library into the 'jni' folder

2) Changed the Android.mk file with the below text.

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := libcom_example_fibonaccinative_FibLib
LOCAL_SRC_FILES := libcom_example_fibonaccinative_FibLib.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := com_example_usingstaticlibrary_LibraryTest
LOCAL_SHARED_LIBRARIES := libcom_example_fibonaccinative_FibLib
LOCAL_SRC_FILES := com_example_usingstaticlibrary_LibraryTest.c
include $(BUILD_SHARED_LIBRARY)

3) Added the .h file from the old project (com_example_fibonaccinative_FibLib.h) into the 'jni' folder

4) Changed the source of com_example_usingstaticlibrary_LibraryTest.c to

#include "com_example_usingstaticlibrary_LibraryTest.h"
#include "com_example_fibonaccinative_FibLib.h"

JNIEXPORT jlong JNICALL Java_com_example_usingstaticlibrary_LibraryTest_callLibraryFunction
(JNIEnv *env, jclass class) {
    Java_com_example_fibonaccinative_FibLib_fibNR(env, class, 500l);
    return -500l;
}

Clean/Build results into the following error

undefined reference to 'Java_com_example_fibonaccinative_FibLib_fibNR'



Edit 2:

With reference to this I've edited the Android.mk as follows

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := com_example_fibonaccinative_FibLib
LOCAL_SRC_FILES := libcom_example_fibonaccinative_FibLib.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := com_example_usingstaticlibrary_LibraryTest
LOCAL_SRC_FILES := com_example_usingstaticlibrary_LibraryTest.c
LOCAL_SHARED_LIBRARIES := com_example_fibonaccinative_FibLib
include $(BUILD_SHARED_LIBRARY)

The NDK build command compiles the code without error. When trying to load the library it gives the following error

Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lcom/example/usingstaticlibrary/LibraryTest

When I remove LOCAL_SHARED_LIBRARIES := com_example_fibonaccinative_FibLib it works fine but I cannot use any function of the Prebuilt shared library.



Edit 3:

I tried a few more things including the suggestion by @jcm but nothing worked. I'm now attaching the source code. It has both the projects (Cleaned version to reduce size).

  1. FibonacciNative: Contains the first project.
  2. UsingStaticLibrary: Contains the second project. I intend to use the Prebuilt Shared Library of the first project into the second one.

解决方案

As you're including libcom_example_fibonaccinative_FibLib.so as LibraryTest's shared library, in your java static method, you should load it before loading LibraryTest:

System.loadlibrary(com_example_fibonaccinative_FibLib);
System.loadLibrary(LibraryTest);

Update:

After checking your code, LibraryTest.java should look like:

package com.kochartech.usingstaticlibrary;

public class LibraryTest {

    public native static long callLibraryFunction();

    static {
        System.loadLibrary("com_kochartech_fibonaccinative_FibLib");
        System.loadLibrary("com_kochartech_usingstaticlibrary_LibraryTest");
    }

}

这篇关于在应用程序中使用外部静态库(NDK)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆