简体   繁体   中英

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

Suppose we have a certain prebuilt native library called libname.a. We need to call a native function contained in the native library from our Java activity. 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.

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. What we did:

  • Installed the NDK and CMake tools.
  • Checked include C++ support while creating the project.
  • Created a jni directory in the project, and copied the files mentioned above.

Our CMakeList.txt file (stored in the project root folder):

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:

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:

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

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

on the C++ side. Your libname does not provide such exported function, therefore you must prepare it yourself, as Richard Critten explained in comments. You can put your wrapper function in file jniWrapper.cpp , next to Android.mk .

Your Android.mk may look like

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; the static constructor of your Java class may look like

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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