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

本文介绍了如何使用Android NDK中的two-libs示例,演示在JNI层调用C文件函数并构建动态库。首先,创建Android工程,编写JNI接口,然后在second.c中调用first.c的函数。接着,通过Android.mk文件编译生成动态库。重点讨论了两种情况:使用静态库libtwolib-first.a生成动态库libtwolib-second.so,以及使用动态库libtwolib-first.so生成libtwolib-second.so。文章提供了所需文件配置和Android.mk的修改方法,以及简化版的mk文件写法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面以NDK提供的two-libs为例子,走一遍如何在jni层调用其他C文件的函数,原例子在second.c这个jni层文件中调用first.c里面的C函数。

通过Androi.mk文件编译生成一个动态库文件。

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");
    }
}


2、编写jni层中间层代码second.c,在其中调用first.c中的first(int x,int y)函数代码:

先看jni层second.c的代码:

#include "first.h"
#include <jni.h>

jint
Java_com_example_twolibs_TwoLibs_add( JNIEnv*  env,
                                      jobject  this,
                                      jint     x,
                                      jint     y )
{
    return first(x, y);
}
first.c中c代码:

#include "first.h"

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

其中first.h中就申明此方法,具体如下:

#ifndef FIRST_H
#define FIRST_H

extern int first(int  x, int  y);

#endif /* FIRST_H */

3、编写Android.mk文件:在此要注意先用first.c生成静态库模块libtwolib-first.a,然后再用其来生成最终的动态库。由此可知,若我们已经编译生成了libtwolib-first.a这个静态库,那么直接用引用它就可以生成最终的libtwolib-second.so 动态库。

LOCAL_PATH:= $(call my-dir)

# first lib, which will be built statically
#
include $(CLEAR_VARS)

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

include $(BUILD_STATIC_LIBRARY)

# second lib, which will depend on and include the first one
#
include $(CLEAR_VARS)

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

LOCAL_STATIC_LIBRARIES := libtwolib-first

include $(BUILD_SHARED_LIBRARY)

4、用NDK来编译生成动态库.so文件,其中静态库可在/obj/local/armeabi目录下找到它。


至此,整个流程完毕,但接下来的才是我想记录的重点内容,我想直接使用libtwolib-first.a,和first.h和与java接口相接的two.c文件来直接生成libtwolib-second.so这个文件。

于是可以扩展到两类问题:


第一:使用静态库来生成动态库。如(libtwolib-first.a 来生成libtwolib-two.so)

第二:使用动态库来生成动态库。如(libtwolib-first.so 来生成libtwolib-two.so)


其中静态库.a文件来生成动态库又可分为单个.a文件和多个.a文件生成.so文件。

第一:即NDK中使用单个静态库来生成动态库问题,前提是这个静态库(动态库)是用NDK编译器编译生成的。

整理需要的文件,将刚生成.a文件拷贝的jni目录下,同时生成first.c文件,用到的文件如下:

thinker@fans:~/android/android-ndk-r9/samples/two-libs/jni$ ls
Android.mk  first.h libtwolib-first.a  second.c

删除刚生成的libs和obj目录,修改Android.mk文件如下:

LOCAL_PATH:= $(call my-dir)

# first lib, which will be built statically
#
include $(CLEAR_VARS)

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

include $(PREBUILT_STATIC_LIBRARY)

# second lib, which will depend on and include the first one
#
include $(CLEAR_VARS)

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

LOCAL_STATIC_LIBRARIES := libtwolib-first

include $(BUILD_SHARED_LIBRARY)

再NDK来编译生成动态库.so文件,如此就OK了。

另一种mk文件的写法也行,而且更加简便:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libtwolib-second
LOCAL_SRC_FILES := second.c
LOCAL_LDFLAGS := libtwolib-first.a
include $(BUILD_SHARED_LIBRARY)


再NDK来编译生成动态库.so文件,如此就OK了。

参考资料:

http://blog.youkuaiyun.com/wjr2012/article/details/6887559



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值