android NDK学习篇3之two-libs——使用(多个)静态库生成动态库

还要以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文件,如:

thinker@fans:~/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文件,如:

thinker@fans:~/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 <stdio.h>
#include <jni.h>
#include <android/log.h> 


//修改日志tag中的值  
#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/lib -llog
include $(BUILD_SHARED_LIBRARY)

方式二:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libtwolib-first
LOCAL_SRC_FILES := first.a
include $(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/lib -llog
include $(BUILD_SHARED_LIBRARY)

4、生成动态库

thinker@fans:~/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 $(CLEAR_VARS)
LOCAL_MODULE    := libtwolib-first
LOCAL_SRC_FILES := first.c
include $(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/lib -llog
include $(BUILD_SHARED_LIBRARY)

编译:

thinker@fans:~/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目录下:

thinker@fans:~/android/android-ndk-r9/samples/two-libs/obj/local/armeabi$ ls
libtwolib-first.a  libtwolib-second.so  libtwolib-third.a  objs

你可能感兴趣的:(android NDK学习篇3之two-libs——使用(多个)静态库生成动态库)