简体   繁体   English

NDK-包括一个预构建的库并在Android Project中调用本机函数

[英]NDK - Include a Prebuilt library and call a native function in Android Project

Suppose we have a certain prebuilt native library called libname.a. 假设我们有一个名为libname.a的预先构建的本地库。 We need to call a native function contained in the native library from our Java activity. 我们需要从Java活动中调用本地库中包含的本地函数。 An example is this one stored in the main header file: 一个示例是此示例存储在主头文件中:

DLLEXPORT int DLLCALL function(Xhandle handle, unsigned char *srcBuf, unsigned char *dstBuf);

Where Xhandle is a struct also defined in the header file. 其中Xhandle是在头文件中也定义的结构。

The files we have are structured as follows: 我们拥有的文件结构如下:

armv6
 |- header1.h
 |- header2.h
 |- ...
 |- libname.a
armv7
 |- header1.h
 |- header2.h
 |- ...
 |- libname.a
x86
 |- header1.h
 |- header2.h
 |- ...
 |- libname.a

We need to import this library into our Android Project. 我们需要将此库导入到我们的Android项目中。 What we did: 我们做了什么:

  • Installed the NDK and CMake tools. 安装了NDK和CMake工具。
  • Checked include C++ support while creating the project. 在创建项目时检查是否包括C ++支持。
  • Created a jni directory in the project, and copied the files mentioned above. 在项目中创建了一个jni目录,并复制了上面提到的文件。

Our CMakeList.txt file (stored in the project root folder): 我们的CMakeList.txt文件(存储在项目根文件夹中):

cmake_minimum_required(VERSION 3.4.1)

add_library( name
             STATIC # We guessed it's a static due to the .a extension
             IMPORTED # No source code (.c or .cpp) available )

We then created an Android.mk file in the jni directory: 然后,我们在jni目录中创建一个Android.mk文件:

LOCAL_PATH := $(call my-dir)
TARGET_ARCH_ABI := armv7

include $(CLEAR_VARS)
LOCAL_MODULE := name
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libname.a
LOCAL_EXPORT_C_INCLUDES := $(TARGET_ARCH_ABI)
include $(PREBUILT_STATIC_LIBRARY)

All of this was deduced from reading the following links: 所有这些都是通过阅读以下链接得出的:

Now in our java activity, we know we need to add something like this: 现在在我们的java活动中,我们知道我们需要添加如下内容:

public native int function();

// Used to load the 'native-lib' library on application startup.
static {
    System.loadLibrary("name");
}

We feel that we did something wrong and that we are missing something. 我们觉得我们做错了什么,而我们缺少了一些东西。 We have to also define the arguments, and we think we should write a wrapper. 我们还必须定义参数,我们认为应该编写一个包装器。

So any help would be appreciated. 因此,任何帮助将不胜感激。

The function native method in your Java class needs Java类中需要的函数本机方法

JNIEXPORT jstring JNICALL Java_my_package_name_MyClass_function(JNIEnv *env, jobject instance)

on the C++ side. 在C ++方面。 Your libname does not provide such exported function, therefore you must prepare it yourself, as Richard Critten explained in comments. 您的libname不提供此类导出的功能,因此您必须自己准备它,如Richard Critten在评论中所解释。 You can put your wrapper function in file jniWrapper.cpp , next to Android.mk . 您可以将包装函数放在Android.mk旁边的文件jniWrapper.cpp中

Your Android.mk may look like 您的Android.mk可能看起来像

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := name
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libname.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(TARGET_ARCH_ABI)
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := jniWrapper
LOCAL_SRC_FILES := jniWrapper.cpp
LOCAL_STATIC_LIBRARIES := name
include $(BUILD_SHARD_LIBRARY)

Finally, lodalLibrary() cannot load static libraries; 最后, lodalLibrary()无法加载静态库。 the static constructor of your Java class may look like Java类的静态构造函数可能看起来像

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM