Android:NDKのシンプルな使い方

9448 ワード

参考にする
JNIはcプログラムをフォーマットに従ってjavaが呼び出すことができる関数インタフェースにカプセル化することができる.
1、javac生成.classファイル
2、javah-jni生成.hファイル
3.hファイルによって.cファイルを修正する.
NDKは、JNIでカプセル化した後、.cファイルを一定のルールでライブラリにコンパイルするツールです.
1、ここのルールはAndroid.mkファイルです.
2、動的ライブラリとしてコンパイルしてもよいし、静的ライブラリとしてコンパイルしてもよい.
1、NDKダウンロード:
https://dl.google.com/android/repository/android-ndk-r14b-linux-x86_64.zip
ここでダウンロードしたのは現在の最新バージョン:r14bです.
2、配置環境
以下、環境設定を行いますubuntu14.04の下に/usr/local/ndkディレクトリを新設し、
①:さっきダウンロードしたndkソースパッケージを、そのディレクトリにコピーし、解凍します.
②:~/.bashrcファイルを開き、ファイルの最後に、以下の内容を追加する.
export PATH=/usr/local/ndk/android-ndk-r14b/:$PATH 
source ~/.bashrcコマンドを使用して、環境変数を更新します.
3、NDKをテストする
ubuntuでは、ndkが正しく構成されているかどうかをテストするコマンドを使用します.root@ubuntu:/neo/c# ndk-build -v GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This program built for x86_64-pc-linux-gnu root@ubuntu:/neo/c#
以上のように、ndk環境構成が完了しました.
4、NDKでダイナミックライブラリをコンパイルする
分かりやすいように、JNIベースでダイナミックライブラリをコンパイルします.
JNIプログラムのリファレンスリンク:
https://blog.csdn.net/weixin_38184741/article/details/91461231
4.1 Android.mkプロファイル
ndk-buildツールを使用してndkコンパイルを行う場合は、プロファイルのルールに従ってコンパイルする必要があります.ここでいうプロファイルはAndroid.mkファイルです.
Android.mkの内容は:
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE:= HelloWorldNDK
LOCAL_SRC_FILES:= HelloWorld.c
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_EXPORT_LDLIBS := -llog

#include $(BUILD_STATIC_LIBRARY)
include $(BUILD_SHARED_LIBRARY)

次のようになります.LOCAL_PATH:= $(call my-dir)は現在のディレクトリを表します.include $(CLEAR_VARS)は、パージ前の構成を示す.一般和
include $(BUILD_STATIC_LIBRARY)	
include $(BUILD_SHARED_LIBRARY)
include $(PREBUILT_STATIC_LIBRARY)
include $(PREBUILT_SHARED_LIBRARY)

組み合わせて使用します(他にもあるはずですが、深く検討していません.以前のモジュールの構成をクリアすることを理解しています(LOCAL_PATHを除きます).LOCAL_MODULEは、コンパイルされたライブラリの名前を表します.LOCAL_SRC_FILESは、ソースファイルのパスおよびコマンドを表します.LOCAL_EXPORT_C_INCLUDESはヘッダファイルが存在するディレクトリを示す.LOCAL_EXPORT_LDLIBSは、ロードする必要がある標準ライブラリを示します.-llogは、デバッグ情報を出力するためにliblogライブラリをロードすることを示す.include $(BUILD_SHARED_LIBRARY)は動的ライブラリにコンパイルすることを示し、include $(BUILD_STATIC_LIBRARY)は静的ライブラリにコンパイルされていることを示しています.ここではブロックします.静的ライブラリは一般的に大きいです.
4.2 NDKのコンパイル
次にNDKダイナミックライブラリをコンパイルします.プロファイルは上に示します.
root@ubuntu:~/ken/jni# ndk-build 
[arm64-v8a] Compile: HelloWorldNDK <= HelloWorld.c
In file included from /root/ken/jni/HelloWorld.c:1:
/root/ken/jni/jni.h:45:10: fatal error: 'jni_md.h' file not found
#include "jni_md.h"
 ^
1 error generated.
make: *** [/root/ken/obj/local/arm64-v8a/objs/HelloWorldNDK/HelloWorld.o] Error 1

jniで参照されているヘッダファイルが見つからないことを示します.以前は-Iパラメータを使用してヘッダファイルパスをロードして解決しました.
ndkのライブラリにもjni.hヘッダファイルがあるので、jni.hファイルを削除できます.
jni.hファイルを削除した後、コンパイルを続行します.
root@ubuntu:~/ken/jni# ndk-build 
[arm64-v8a] Compile: HelloWorldNDK <= HelloWorld.c
[arm64-v8a] SharedLibrary  : libHelloWorldNDK.so
[arm64-v8a] Install: libHelloWorldNDK.so => libs/arm64-v8a/libHelloWorldNDK.so
[x86_64] Compile: HelloWorldNDK <= HelloWorld.c
[x86_64] SharedLibrary  : libHelloWorldNDK.so
[x86_64] Install: libHelloWorldNDK.so => libs/x86_64/libHelloWorldNDK.so
[mips64] Compile: HelloWorldNDK <= HelloWorld.c
[mips64] SharedLibrary  : libHelloWorldNDK.so
[mips64] Install: libHelloWorldNDK.so => libs/mips64/libHelloWorldNDK.so
[armeabi-v7a] Compile thumb  : HelloWorldNDK <= HelloWorld.c
[armeabi-v7a] SharedLibrary  : libHelloWorldNDK.so
[armeabi-v7a] Install: libHelloWorldNDK.so => libs/armeabi-v7a/libHelloWorldNDK.so
[armeabi] Compile thumb  : HelloWorldNDK <= HelloWorld.c
[armeabi] SharedLibrary  : libHelloWorldNDK.so
[armeabi] Install: libHelloWorldNDK.so => libs/armeabi/libHelloWorldNDK.so
[x86] Compile: HelloWorldNDK <= HelloWorld.c
[x86] SharedLibrary  : libHelloWorldNDK.so
[x86] Install: libHelloWorldNDK.so => libs/x86/libHelloWorldNDK.so
[mips] Compile: HelloWorldNDK <= HelloWorld.c
[mips] SharedLibrary  : libHelloWorldNDK.so
[mips] Install: libHelloWorldNDK.so => libs/mips/libHelloWorldNDK.so
root@ubuntu:~/ken/jni# 

現在のディレクトリの下でライブラリファイルを生成するのではなく、前のディレクトリの下にあることがわかります.これは私たちの習慣に合わない.ndk-build clean後、パラメータを追加し、コンパイルを続行します.
root@ubuntu:~/ken/jni# 
root@ubuntu:~/ken/jni# ndk-build clean
[arm64-v8a] Clean  : HelloWorldNDK [arm64-v8a]
[arm64-v8a] Clean  : stdc++ [arm64-v8a]
[x86_64] Clean  : HelloWorldNDK [x86_64]
[x86_64] Clean  : stdc++ [x86_64]
[mips64] Clean  : HelloWorldNDK [mips64]
[mips64] Clean  : stdc++ [mips64]
[armeabi-v7a] Clean  : HelloWorldNDK [armeabi-v7a]
[armeabi-v7a] Clean  : stdc++ [armeabi-v7a]
[armeabi] Clean  : HelloWorldNDK [armeabi]
[armeabi] Clean  : stdc++ [armeabi]
[x86] Clean  : HelloWorldNDK [x86]
[x86] Clean  : stdc++ [x86]
[mips] Clean  : HelloWorldNDK [mips]
[mips] Clean  : stdc++ [mips]
root@ubuntu:~/ken/jni# ndk-build NDK_PROJECT_PATH=. 
Android NDK: Your APP_BUILD_SCRIPT points to an unknown file: ./jni/Android.mk
/usr/local/ndk/android-ndk-r14b/build/core/add-application.mk:198: *** Android NDK: Aborting....  Stop.
root@ubuntu:~/ken/jni# ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk 
[arm64-v8a] Compile: HelloWorldNDK <= HelloWorld.c
[arm64-v8a] SharedLibrary  : libHelloWorldNDK.so
[arm64-v8a] Install: libHelloWorldNDK.so => libs/arm64-v8a/libHelloWorldNDK.so
[x86_64] Compile: HelloWorldNDK <= HelloWorld.c
[x86_64] SharedLibrary  : libHelloWorldNDK.so
[x86_64] Install: libHelloWorldNDK.so => libs/x86_64/libHelloWorldNDK.so
[mips64] Compile: HelloWorldNDK <= HelloWorld.c
[mips64] SharedLibrary  : libHelloWorldNDK.so
[mips64] Install: libHelloWorldNDK.so => libs/mips64/libHelloWorldNDK.so
[armeabi-v7a] Compile thumb  : HelloWorldNDK <= HelloWorld.c
[armeabi-v7a] SharedLibrary  : libHelloWorldNDK.so
[armeabi-v7a] Install: libHelloWorldNDK.so => libs/armeabi-v7a/libHelloWorldNDK.so
[armeabi] Compile thumb  : HelloWorldNDK <= HelloWorld.c
[armeabi] SharedLibrary  : libHelloWorldNDK.so
[armeabi] Install: libHelloWorldNDK.so => libs/armeabi/libHelloWorldNDK.so
[x86] Compile: HelloWorldNDK <= HelloWorld.c
[x86] SharedLibrary  : libHelloWorldNDK.so
[x86] Install: libHelloWorldNDK.so => libs/x86/libHelloWorldNDK.so
[mips] Compile: HelloWorldNDK <= HelloWorld.c
[mips] SharedLibrary  : libHelloWorldNDK.so
[mips] Install: libHelloWorldNDK.so => libs/mips/libHelloWorldNDK.so
root@ubuntu:~/ken/jni# 
root@ubuntu:~/ken/jni# ls
Android.mk  HelloWorld.c  HelloWorld.class  HelloWorld.h  HelloWorld.java  libHelloWorld.so  libs  obj
root@ubuntu:~/ken/jni# 

以上より、ndk-buildを使用する場合、2つのパラメータNDK_PROJECT_PATHAPP_BUILD_SCRIPTを追加し、エンジニアリングパスとプロファイルパスを指定します.
コンパイルされたライブラリの状況を表示します.
root@ubuntu:~/ken/jni/libs# file */*
arm64-v8a/libHelloWorldNDK.so:   ELF 64-bit LSB  shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=a63502fc8bb3907cd4f122d6aa1867b7423dc7dd, stripped
armeabi/libHelloWorldNDK.so: ELF 32-bit LSB  shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=56d98623f4f90a52ca681bd88768c520a999b722, stripped
armeabi-v7a/libHelloWorldNDK.so: ELF 32-bit LSB  shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=f66ea129183665d8384f0df51dbe3c655890b35e, stripped
mips64/libHelloWorldNDK.so:  ELF 64-bit LSB  shared object, MIPS, version 1 (SYSV), dynamically linked, BuildID[sha1]=087e1f1cd4859a68c7ea2a06c6932cd10cbb87dc, stripped
mips/libHelloWorldNDK.so:ELF 32-bit LSB  shared object, MIPS, MIPS32 version 1 (SYSV), dynamically linked, BuildID[sha1]=d49923384cc67942af6f3b1dd83fa7a89a4c1139, stripped
x86_64/libHelloWorldNDK.so:  ELF 64-bit LSB  shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=fa7710bd5ce6964995bcc8be52aadcd422cf8acb, stripped
x86/libHelloWorldNDK.so: ELF 32-bit LSB  shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=f91da4f4c467ebd8cf4b28d237336a48a719d308, stripped
root@ubuntu:~/ken/jni/libs# cd ../obj/
root@ubuntu:~/ken/jni/obj# tree */*
local/arm64-v8a
├── libHelloWorldNDK.so
└── objs
└── HelloWorldNDK
├── HelloWorld.o
└── HelloWorld.o.d
local/armeabi
├── libHelloWorldNDK.so
└── objs
└── HelloWorldNDK
├── HelloWorld.o
└── HelloWorld.o.d
local/armeabi-v7a
├── libHelloWorldNDK.so
└── objs
└── HelloWorldNDK
├── HelloWorld.o
└── HelloWorld.o.d
local/mips
├── libHelloWorldNDK.so
└── objs
└── HelloWorldNDK
├── HelloWorld.o
└── HelloWorld.o.d
local/mips64
├── libHelloWorldNDK.so
└── objs
└── HelloWorldNDK
├── HelloWorld.o
└── HelloWorld.o.d
local/x86
├── libHelloWorldNDK.so
└── objs
└── HelloWorldNDK
├── HelloWorld.o
└── HelloWorld.o.d
local/x86_64
├── libHelloWorldNDK.so
└── objs
└── HelloWorldNDK
├── HelloWorld.o
└── HelloWorld.o.d

14 directories, 21 files
root@ubuntu:~/ken/jni/obj# 

コンパイルされたライブラリはappに呼び出すことができます.