欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

NDK 生成动态链接库

程序员文章站 2022-06-25 18:45:42
...

android NDK學習篇3之two-libs——使用(多個)靜態庫生成動態庫
2013年08月16日 ⁄ 綜合 ⁄ 共 4599字 ⁄ 字號 小 中 大 ⁄ 評論關閉

還要以NDK提供的two-libs為例子,走一遍多個靜態庫(.a文件)生成動態庫(.so文件)的流程。

1、建立android工程,編寫java對應JNI層的本地接口:

package com.example.twolibs;

import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;

public class TwoLibs extends Activity
{
/* Called when the activity is first created. /
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);

    TextView  tv = new TextView(this);
    int       x  = 1000;
    int       y  = 42;

    // here, we dynamically load the library at runtime
    // before calling the native method.
    //

    int  z = add(x, y);

    tv.setText( "The sum of " + x + " and " + y + " is " + z );
    setContentView(tv);

}

public native int add(int  x, int  y);

static
{
    System.loadLibrary("twolib-second");
}

}
JNI文件夾下的準備預備文件如下,其中.o和.a文件都是用NDK編譯生成,具體操作見下:

Android.mk first.c first.o third.a third.h
first.a first.h second.c third.c third.o
2、編寫jni層中間層代碼second.c,在其中調用first.c中的first(int x,int y)函數及third.c中的test()函數,具體代碼如下:

first.h頭文件如下:

ifndef FIRST_H

define FIRST_H

extern int first(int x, int y);

endif /* FIRST_H */

first.c中c代碼:

include “first.h”

int first(int x, int y)
{
return x + y;
}

現在就用NDK的提供的C編譯器來編譯生成firs.a這個靜態庫,用於後續生成libtwolib-second.so動態庫的源文件。步驟跟linux下編譯生成靜態庫方法完全一樣.

第一步:找到NDK下自帶的gcc和ar,/android-ndk-r9e/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/

第二步:用NDK的gcc編譯器來生成.a文件,如:

[email protected]:~/android/android-ndk-r9/samples/two-libs/jni$ ../../../toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc -o first.o -c first.c
第三步:用NDK的ar工具來生成.a文件,如:

[email protected]:~/android/android-ndk-r9/samples/two-libs/jni$ ../../../toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-ar rcs first.a first.o
到此OK,生成了first.a靜態庫文件。類似步驟生成third.a庫。

third.h如:

ifndef THIRD_H

define THIRD_H

extern int third();

endif /* THIRD_H */

third.c中c代碼:

include “third.h”

int third()
{
return 10;
}
jni層中間層代碼second.c如下:

include “first.h”

include “third.h”

include

include

include

define LOG_TAG “log_from_second.c”

//日誌顯示的等級

define LOGD(…) android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS)

define LOGI(…) android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS)

jint
Java_com_example_twolibs_TwoLibs_add( JNIEnv* env,
jobject this,
jint x,
jint y )
{
int i = third();
LOGI(“the test result = %d”,i);
return first(x, y);
}
3、編寫Android.mk文件:如下兩種方式都可以,用於NDK編譯工具生成的兩個.a文件來生成最終的libtwolib-second.so 動態庫。

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := libtwolib-second
LOCAL_SRC_FILES := second.c

LOCAL_LDFLAGS := first.a third.a
LOCAL_LDLIBS:=-L(SYSROOT)/usr/liblloginclude(BUILD_SHARED_LIBRARY)
方式二:

LOCAL_PATH:= $(call my-dir)

include (CLEARVARS)LOCALMODULE:=libtwolibfirstLOCALSRCFILES:=first.ainclude(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := libtwolib-third
LOCAL_SRC_FILES := third.a

include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := libtwolib-second
LOCAL_SRC_FILES := second.c

LOCAL_STATIC_LIBRARIES := libtwolib-first libtwolib-third
LOCAL_LDLIBS:=-L(SYSROOT)/usr/liblloginclude(BUILD_SHARED_LIBRARY)
4、生成動態庫

[email protected]:~/android/android-ndk-r9/samples/two-libs/jni$ /home/thinker/android/android-ndk-r8e/ndk-build
/home/thinker/android/android-ndk-r8e/build/core/add-application.mk:128: Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 3 in /home/thinker/android/android-ndk-r9/samples/two-libs/AndroidManifest.xml
Compile thumb : twolib-second <= second.c
SharedLibrary : libtwolib-second.so
Install : libtwolib-second.so => libs/armeabi/libtwolib-second.so
運行查看打印信息,一切OK。

參考網址:

http://blog.csdn.net/wjr2012/article/details/6887559

附:

可以直接編寫Android.mk文件來生成兩個.a文件,如下:

LOCAL_PATH:= $(call my-dir)

include (CLEARVARS)LOCALMODULE:=libtwolibfirstLOCALSRCFILES:=first.cinclude(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := libtwolib-third
LOCAL_SRC_FILES := third.c

include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := libtwolib-second
LOCAL_SRC_FILES := second.c

LOCAL_STATIC_LIBRARIES := libtwolib-first libtwolib-third
LOCAL_LDLIBS:=-L(SYSROOT)/usr/liblloginclude(BUILD_SHARED_LIBRARY)
編譯:

[email protected]:~/android/android-ndk-r9/samples/two-libs/jni$ ../../../../android-ndk-r8e/ndk-build
/home/thinker/android/android-ndk-r8e/build/core/add-application.mk:128: Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 3 in /home/thinker/android/android-ndk-r9/samples/two-libs/AndroidManifest.xml
Compile thumb : twolib-second <= second.c
Compile thumb : twolib-first <= first.c
StaticLibrary : libtwolib-first.a
Compile thumb : twolib-third <= third.c
StaticLibrary : libtwolib-third.a
SharedLibrary : libtwolib-second.so
Install : libtwolib-second.so => libs/armeabi/libtwolib-second.so
生成的.a文件在工程/obj/local/armeabi目錄下:

[email protected]:~/android/android-ndk-r9/samples/two-libs/obj/local/armeabi$ ls
libtwolib-first.a libtwolib-second.so libtwolib-third.a objs

相关标签: ndk 动态链接库