Android Studio下的NDK开发(四):调用动态链接库中的函数

1、编写Hello.c,代码如下


#include "Hello.h"

int sum(int a, int b){
    return a+b;
}


2、编写Hello.h,代码如下


#ifndef JNIDEMO_IV_HELLO_H
#define JNIDEMO_IV_HELLO_H

int sum(int, int);

#endif //JNIDEMO_III_HELLO_H


3、通过CMakelist编译成libHello.so,CmakeLists.txt代码如下


cmake_minimum_required(VERSION 3.4.1)

add_library( # Sets the name of the library.
             Hello

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             #src/main/jni/com_jnidemo_iv_JniUntil.c
             src/main/jni/Hello.c
             )


find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

target_link_libraries( # Specifies the target library.
                      
                        Hello
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

4、在build.gradle的android{ }下加入如下代码:


// 设置so文件路径
sourceSets {
    main {
        jniLibs.srcDirs = ['libs']
    }
}

5、将Hello.so拷贝到libs目录下,并在libs目录下新建jpeg文件夹,将Hello.h拷贝到jpeg文件夹中

Android Studio下的NDK开发(四):调用动态链接库中的函数



6、编写JniUtil类native方法,代码如下

public class JniUtil {
    public native int sum(int a,int b);


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




7、删掉cpp文件夹中的Hello.c和Hello.h,再新建com_jnidemo_iv_JniUtil.c和com_jnidemo_iv_JniUtil.h,代码如下:

com_jnidemo_iv_JniUtil.c


#include "com_jnidemo_iv_JniUtil.h"
//声明在Hello.c中的sum函数
int sum(int, int);

JNIEXPORT jint JNICALL Java_com_jnidemo_1iv_JniUtil_sum
        (JNIEnv *env, jobject object, jint a, jint b){
    //调用Hello.c中的sum函数
    return sum(a,b);
}



com_jnidemo_iv_JniUtil.h



#include <jni.h>

//引入Hello.h
#include "Hello.h"
/* Header for class com_jnidemo_iv_JniUtil */

#ifndef _Included_com_jnidemo_iv_JniUtil
#define _Included_com_jnidemo_iv_JniUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_jnidemo_iv_JniUtil
 * Method:    sum
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_jnidemo_1iv_JniUtil_sum
  (JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#endif


8、编辑CMakeLists.txt,代码如下


# Sets the minimum version of CMake required to build the native
# library. You should either keep the default value or only pass a
# value of 3.4.0 or lower.

cmake_minimum_required(VERSION 3.4.1)

#引用已经有的库
find_library( # Sets the name of the path variable.
              log-lib

               # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

#资源文件夹的位置libs
set(distribution_DIR ${CMAKE_SOURCE_DIR}/../../../../libs)

#导入类库,只是作为引用,不编译
add_library( Hello
             SHARED
             IMPORTED )

#引用目标类库是本地类库位置在libs/armeabi-v7a/libHello.so
set_target_properties( Hello
                       PROPERTIES IMPORTED_LOCATION
                       ../../../../libs/armeabi-v7a/libHello.so )

#添加类库位置在src/main/cpp/xxx.cpp需要编译
add_library(demo_lib
             SHARED
             src/main/cpp/com_jnidemo_iv_JniUtil.c)

#引入头文件目录位置
include_directories(libs/jpeg)

#将预构建库与你本地库相关联
target_link_libraries( # Specifies the target library.
                       demo_lib Hello

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )


9、rebuild 重新编译项目

可以看到cpp下有两个Library,一个是我们新编译的demo_lib,一个则是我们调用的Hello的库,里面没有C文件,只有一个动态链接库


Android Studio下的NDK开发(四):调用动态链接库中的函数


再将cmake中新编译成的demo_lib.so拷贝到lib 


Android Studio下的NDK开发(四):调用动态链接库中的函数



10、编写MainActivity类调用native函数,代码如下:


public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        JniUtil util=new JniUtil();
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(util.sum(10,4)+"");
    }

}

11、运行结果

Android Studio下的NDK开发(四):调用动态链接库中的函数


12、源码链接

点击打开链接