Android 如何編譯和使用外部so文件

[TOC]

故事場(chǎng)景

android通常使用別人的輪子是直接依賴別人的aar,但是如果別人扔給你一個(gè)so和一個(gè).h文件狭魂,我們需要如何使用壹蔓,本工程將演示直接在ndk文件中鏈接so并在工程中使用味咳。

編譯庫(kù)文件

工程結(jié)構(gòu)

image

hello.h

提供 libhello.so和對(duì)應(yīng)的.h文件 hello.h 如下

#ifndef HELLO_H 
#define HELLO_H 
#include <stdio.h> 
int HelloAdd(int a,int b);
#endif

其中 HelloAdd方法實(shí)現(xiàn)了a+b的操作,接下來(lái)將調(diào)用此函數(shù)實(shí)現(xiàn)功能陷舅。

hello.cpp

#include "hello.h"
int HelloAdd(int a,int b)
{
     int result=a+b;
     printf("HelloAdd:result=%d \n",result);
     return result;
}

CmakeLists.txt

SET(LIBHELLO_SRC hello.cpp)

ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)

ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)

INSTALL(TARGETS hello hello_static
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib)
INSTALL(FILES hello.h DESTINATION include/hello)

此示例是演示了動(dòng)態(tài)和靜態(tài)庫(kù)兩種編譯方式

編譯

模塊下有一個(gè)腳本cmake_build_all.sh,直接在終端執(zhí)行
cmake_build_all.sh libhello.so
則可輸出以下文件:

image

注意:cmake_build_all.sh腳本信賴于環(huán)境變量ANDROID_SDK_PATH的配置审洞,比如:
export ANDROID_SDK_PATH=/Users/Shared/ShareLib/Android/sdk

使用庫(kù)文件

創(chuàng)建ndk工程

配置工程為cmake編譯

在應(yīng)用的build.gradle中配置

externalNativeBuild {
        cmake {
            path 'CMakeLists.txt'
        }
    }

當(dāng)前目錄創(chuàng)建CmakeLists.txt文件

cmake_minimum_required(VERSION 3.4.1)
add_subdirectory(src/main/cpp/jni)

在對(duì)應(yīng)的“src/main/cpp/jni”文件下再創(chuàng)建以下文件

image

其中CmakeLists.txt文件的內(nèi)容為

cmake_minimum_required(VERSION 3.4.1)
add_library(math_test SHARED math_test.cc)

創(chuàng)建有native方法的java類MathTest

package com.sen.ndk.buildexternso;
public class MathTest {

    public static native int add(int a, int b);

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

因此需要定義Java_com_sen_ndk_buildexternso_MathTest_add方法

定義math_test.h文件

#ifndef BUILDEXTERNSO_MATH_TEST_H
#define BUILDEXTERNSO_MATH_TEST_H
#include <jni.h>
#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jint JNICALL Java_com_sen_ndk_buildexternso_MathTest_add
    (JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#endif //BUILDEXTERNSO_MATH_TEST_H

創(chuàng)建math_test.cc文件莱睁,目前還未使用so,直接返回相加值可測(cè)試工程運(yùn)行


#include "math_test.h"

JNIEXPORT jint JNICALL Java_com_sen_ndk_buildexternso_MathTest_add
    (JNIEnv * env, jobject jo, jint a, jint b){

  return a+b;
}


使用hello.so文件

拷貝hello.h文件

#ifndef HELLO_H 
#define HELLO_H 
#include <stdio.h> 
extern int HelloAdd(int a,int b); 
#endif

更新main.cpp

#include "hello.h"
int HelloAdd(int a,int b)
{
     int result=a+b;
     printf("HelloAdd:result=%d \n",result);
     return result;
}

更新cmake文件

cmake_minimum_required(VERSION 3.4.1)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)


add_library(hello SHARED IMPORTED)
set_target_properties(hello PROPERTIES IMPORTED_LOCATION
        ${PROJECT_LIBS_DIR}/${ANDROID_ABI}/libhello.so)

add_library(math_test SHARED math_test.cc)
target_include_directories(math_test PUBLIC ${hello_INCLUDE})
TARGET_LINK_LIBRARIES(math_test hello)

以上庫(kù)的連接文件是動(dòng)態(tài)連接芒澜,意味著當(dāng)前工程就包連接hello庫(kù)仰剿,也需要將hello庫(kù)打包在工程中,因此需要將庫(kù)文件拷貝到"src/main/jniLibs"目錄下痴晦,至此整個(gè)依賴關(guān)系可完成南吮。

示例代碼

示例代碼

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市誊酌,隨后出現(xiàn)的幾起案子部凑,更是在濱河造成了極大的恐慌露乏,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涂邀,死亡現(xiàn)場(chǎng)離奇詭異施无,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)必孤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門(mén)猾骡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人敷搪,你說(shuō)我怎么就攤上這事兴想。” “怎么了赡勘?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵嫂便,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我闸与,道長(zhǎng)毙替,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任践樱,我火速辦了婚禮厂画,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拷邢。我一直安慰自己袱院,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布瞭稼。 她就那樣靜靜地躺著忽洛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪环肘。 梳的紋絲不亂的頭發(fā)上欲虚,一...
    開(kāi)封第一講書(shū)人閱讀 49,730評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音悔雹,去河邊找鬼复哆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛荠商,可吹牛的內(nèi)容都是我干的寂恬。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼莱没,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼初肉!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起饰躲,我...
    開(kāi)封第一講書(shū)人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤牙咏,失蹤者是張志新(化名)和其女友劉穎臼隔,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體妄壶,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摔握,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丁寄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氨淌。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖伊磺,靈堂內(nèi)的尸體忽然破棺而出盛正,到底是詐尸還是另有隱情,我是刑警寧澤屑埋,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布豪筝,位于F島的核電站,受9級(jí)特大地震影響摘能,放射性物質(zhì)發(fā)生泄漏续崖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一团搞、第九天 我趴在偏房一處隱蔽的房頂上張望严望。 院中可真熱鬧,春花似錦莺丑、人聲如沸著蟹。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至奸披,卻和暖如春昏名,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背阵面。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工轻局, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人样刷。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓仑扑,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親置鼻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子镇饮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容