使用 NDK-Build 创建一个最小的 so 库

194 阅读1分钟

概述

首先 NDK-Build 是一个指令,它存放在 NDK 的目录中,打开就能看到。

image.png

下面介绍下整体的步骤:

  1. 创建一个java文件,其中定义一个简单的 native 方法。
  2. 通过 javah 或者 javac -h 生成对应的头文件。
  3. 创建 cpp 文件做相关的实现。
  4. 创建 Android.mk 文件。
  5. 运行 ndk-build 生成so。

1. 创建 java 文件

这一步很简单咯,只需要在里面放一个 native 方法就可以了,我们放一个返回 string 的native 方法,如下:

public class JNITest {
   static {
      System.loadLibrary("your_lib_name");
   }

   public native String getSomeString();
}

其中 static 代码块是用来加载最终编译的 so 库的。

2. 生成头文件

使用 javah 或者 javac -h 生成对应的头文件,类似这样:

javac -h {生成的目录} {xxx.java}

你会得到一个.h的头文件,内容类似这样:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_test_jni_JNITest */

#ifndef _Included_com_test_jni_JNITest
#define _Included_com_test_jni_JNITest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_test_jni_JNITest
 * Method:    getSomeString
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_test_jni_JNITest_getSomeString
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

生成的头文件需要放在 jni 目录中,类似这样:

main 
 ├── java 
 └── jni

3. 编写 cpp 文件,实现逻辑

只是一个演示,简单的返回一个字符串。

#include <jni.h>
#include "com_test_jni_JNITest.h"
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jstring JNICALL Java_com_test_jni_JNITest_getSomeString(JNIEnv * env, jobject) {
    return env->NewStringUTF("abcd");
}

#ifdef __cplusplus
}
#endif

4. 创建 Android.mk 文件

这个文件是用来指导要如何生成 so 文件,内容大致是这样。

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := your_lib_name
LOCAL_SRC_FILES := com_test_jni_JNITest.cpp

include $(BUILD_SHARED_LIBRARY)

5. 运行 ndk-build

接下来直接在命令行运行 ndk-build,应该就ok了。