在应用程序中使用外部静态库(NDK) [英] Use external static library in application (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 。它有两个项目(清洗版本,以减少大小)。
- FibonacciNative:包含的第一个项目
- 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).
- FibonacciNative: Contains the first project.
- 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屋!