Ndk jni编译so,亲测可用~_~

https://blog.csdn.net/qq_35071078/article/details/70502481

使用ndk-build构建Jni
ndk-build是什么
ndk-build 文件是 Android NDK r4 中引入的一个 shell 脚本。其用途是调用正确的 NDK 构建脚本。可以用这个命令来生成.so文件。

ndk-build如何使用
当你想使用该命令将.cpp/.c文件生成.so文件,必须有具备以下几个条件

需有有Android.mk文件,并且与对应的.cpp/.c文件在同一个目录下

需要有Application.mk文件,并且与对应的.cpp/.c文件在用一个目录下

什么是Android.mk
Android.mk 文件位于项目 jni/ 目录的子目录中,用于向构建系统描述源文件和共享库。 它实际上是构建系统解析一次或多次的微小 GNU makefile 片段。 Android.mk 文件用于定义 Application.mk、构建系统和环境变量所未定义的项目范围设置。 它还可替换特定模块的项目范围设置。 
Android.mk 的语法用于将源文件分组为模块。 模块是静态库、共享库或独立可执行文件。 可在每个 Android.mk 文件中定义一个或多个模块,也可在多个模块中使用同一个源文件。 构建系统只会将共享库放入应用软件包。 此外,静态库可生成共享库。 
除了封装库之外,构建系统还可为您处理各种其他详细信息。例如,您无需在 Android.mk 文件中列出标头文件或生成的文件之间的显式依赖关系。 NDK 构建系统会自动为您计算这些关系。 因此,您应该能够享受到未来 NDK 版本中新工具链/平台支持的优点,而无需接触 Android.mk 文件。 
此文件的语法与随整个 Android 开放源代码项目分发的 Android.mk 文件中使用的语法非常接近。 虽然使用它们的构建系统实现不同,但类似之处在于,其设计决定旨在使应用开发者更容易重复使用外部库的源代码。 
简单来说,这个文件可以定义生成的.so文件的名字,可以像.cpp/.c文件引入一些动态库。 
具体可以去看谷歌官方的参考

什么是Application.mk
Application.mk 文件实际上是定义要编译的多个变量的微小 GNU Makefile 片段。 它通常位于 PROJECT/jni/下,其中PROJECT/jni/下,其中PROJECT 指向应用的项目目录。 另一种方式是将其放在顶级 $NDK/apps/ 目录的子目录下。 
例如,Application.mk可以用来指定需要生成哪些cpu类型的.so文件,或者定义引用.so的最低android api。 
详细请看谷歌官方参考

示例
首先创建一个项目: 

用javah命令生成.h文件:首先 cd app/build/intermediates/classes/debug 进入到debug目录,然后 javah com.chenxin.testndk.MyJni 生成.h文件,在app/src/main目录下创建一个jni文件夹,将刚才生成的.h文件剪切到jni文件夹里面,在jni文件夹里面创建一个.c/.cpp的文件 

如果创建的是.c:

#include <com_chenxin_testndk_MyJni.h>
#include <android/log.h>

#define LOG_TAG "infoo"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

JNIEXPORT jstring JNICALL Java_com_chenxin_testndk_MyJni_get
  (JNIEnv *env, jclass jz){

        LOGI("hello,这里是native层");
        return (*env)->NewStringUTF(env,"hello jni , you are so easy!");

  }


如果是.cpp:

#include <com_chenxin_testndk_MyJni.h>
#include <android/log.h>

#define LOG_TAG "infoo"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

JNIEXPORT jstring JNICALL Java_com_chenxin_testndk_MyJni_get
  (JNIEnv *env, jclass jz){

        LOGI("hello,这里是native层");
        return env->NewStringUTF("hello jni , you are so easy!");

  }

在jni目录下创建Android.mk文件:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := MyJni 
LOCAL_SRC_FILES := test.c
LOCAL_LDLIBS +=-L$(SYSROOT)/usr/lib -lm -llog
include $(BUILD_SHARED_LIBRARY)

LOCAL_MODULE:是将要生成的.so的名字
LOCAL_SRC_FILES:是需要将哪个.c/.cpp文件生成.so文件,例如我这里是test.c
LOCAL_LDLIBS:这里是给.c/.cpp文件添加了一个log库,可以打印log


在jni目录下创建Application.mk文件

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := all
APP_PLATFORM := android-8


APP_ABI:是将要生成哪些cpu类型的so,all代表全部
 

.c/.cpp,android.mk,application.mk创建完成之后: 

------------------------------------------------------ 运行命令 -------------------------------------------------------

先进入 jni文件夹

/Users/20209527sun/Downloads/NdkSo/app/src/main/jni

在用这

/Users/20209527sun/android-ndk-r12b/ndk-build 

------------------------------------------------------ 亲测可用的几个文件 -------------------------------------------------------

1. king_bird_ndkjnidemo_JNIUtils.h  随便起一个

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

#ifndef _Included_king_bird_ndkjnidemo_JNIUtils
#define _Included_king_bird_ndkjnidemo_JNIUtils
#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jstring JNICALL Java_com_ndk_haha_JNIUtils_printStringByJni
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

2. JNIControl.cpp

#include "king_bird_ndkjnidemo_JNIUtils.h"
//king_bird_ndkjnidemo_JNIUtils_printStringByJni 包名+文件名+文件内方法名
JNIEXPORT jstring JNICALL Java_com_ndk_haha_JNIUtils_printStringByJni
        (JNIEnv *env, jclass jclass){
    //字符串返回
return env->NewStringUTF("哦哦哦123");
}

3.Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := JNIControl
LOCAL_SRC_FILES := JNIControl.cpp
LOCAL_LDLIBS +=-L$(SYSROOT)/usr/lib -lm -llog
include $(BUILD_SHARED_LIBRARY)

4. Application.mk

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := all
APP_PLATFORM := android-8

5.

package com.ndk.haha;
public class JNIUtils {
    static {
        System.loadLibrary("JNIControl");
    }
    public static native String printStringByJni();
}
String str = JNIUtils.printStringByJni();
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值