使用ndk-build編譯 android調用的so庫

前沿

編譯so的方法有兩種方法第一種就是編寫原生的makefile文件利用gcc進行編譯,這裏我講解的是另一種。採用NDK提供的ndk-build編譯。java

簡介

使用ndk編譯的時候須要介紹它的腳本文件,Android.mk和Application.mk,可是Application.mk是可選的,用來描述原生程序用到的一些特性,如原生程序支持的ARM指令集。android

Android.mk是工程的編譯腳本,描述了編譯原生程序所須要的選擇項、頭文件、源文件以及依賴庫等。c++

實例

首先須要下載DNK,這個就不用多說了,我直接來講步驟吧。程序員通常都會對Hello,world感到親切,咱們就從hello,word開始。利用eclipse新建一個項目我取了新建了一個andoridNDKTest這個項目,先看看項目目錄吧。程序員

這裏注意到上面的多了一個jni目錄,這個目錄就是java經過jni調用的代碼放的地方,裏面放了三個文件,咱們仍是首先來說一下hello-jni.c這個文件,咱們來看看代碼。eclipse

#include <string.h>  
#include <jni.h>  
jstring  
Java_com_example_ndktest_MainActivity_stringFromJNI( JNIEnv* env,  
                                                  jobject thiz )  
{  
    return (*env)->NewStringUTF(env, "Hello world ");  
}

代碼很簡單就是命名有點長,第一個Java不用管就是jni的規定,而後後面的就是包路徑和類名稱最後是函數名。這個函數的做用就是返回一個字符串。
ide

而後就是利用ndk來編譯這個函數了,咱們須要看看Android.mk和Applicaion.mk文件裏面到底有些什麼。函數

android.mkui

LOCAL_PATH := $(call my-dir)  
  
include $(CLEAR_VARS)  
  
LOCAL_MODULE    := hello  
LOCAL_SRC_FILES := hello-jni.c  
  
include $(BUILD_SHARED_LIBRARY)

LOCAL_PATH:=($call my-dir)定義了本地源碼路徑 call my-dir是編譯系統提供的,返回的就是mk的路徑。spa

include $(CLEAR_VARS) 指定讓編譯系統清楚掉一些已經定義過的宏,這些宏定義都是全局的,如LOCAL_MODULE、LOCAL_SRC_FILE,當一個GUN MAKE在編譯多個模塊時候,必須清楚而且從新設置他們。code

LOCAL_ARM_MODE := arm指定原生程序用的指令集,這裏上面咱們沒有用到。

LOCAL_MODULE:= hello指定生成程序的文件名,若是生成共享的庫模塊會生成libhello.so.

LOCAL_SRC_FILE:=hello-jni.c指定c或者c++源文件。

inlude $(BUILD_EXECUTABLE)指定生成文件的類型,BUILD_EXECUTABLE表示可執行文件,BUILD_SHARED_LIBRARY表示生成動態庫,BUILD_STATIC_LIBRARY靜態庫。

而後是Applicaion.mk文件

APP_ABI := all

這句代碼的意思是生成全部平臺的編譯結果。

其實到了這裏你就能夠直接進入jni文件夾裏面輸入ndk-build開始編譯了,可是爲了看到編譯事後的運行結果我這裏在eclipse裏面編譯,看圖說話。

而後編譯器就會自動的編譯文件,最後就是android這邊的調用了,咱們來看看andorid的文件代碼

public class MainActivity extends Activity {  
  
    //聲明c的接口  
    public native String stringFromJNI();  
  
    static {  
        System.loadLibrary("hello");  
    }  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
  
        TextView textView = (TextView) findViewById(R.id.hello);  
        textView.setText(stringFromJNI());  
    }  
}


而後讓咱們注意的是 這句代碼
public native String stringFromJNI();
其實它就是函數生命,可是採用的native由於是在so裏面的。
static {
System.loadLibrary("hello");
}

這句函數就更簡單了,直接加載咱們剛纔編譯好的so庫。好了,若是沒什麼問題就直接run在手機上看效果吧。

相關文章
相關標籤/搜索