android ndk jni 实例1

本文介绍如何检查并封装第三方动态库,使其能在Android环境中通过JNI接口调用。文章详细讲解了所需的文件、步骤及Makefile配置。
1、检查所需文件是否齐全
使用第三方动态库,应该至少有 2 个文件,一个是动态库(.so),另一个是包含
动态库 API 声明的头文件(.h)<wbr></wbr>
例:
Add.c(实际上如果使用第三方库时我们是没有源码的,这里为了方便举例):<wbr></wbr>
#include<stdio.h><wbr></wbr>
int Add(int x, int y)<wbr></wbr>
<wbr><span style="font-size:18px">}</span></wbr>
return x+y;<wbr></wbr>
<wbr><span style="font-size:18px">{</span></wbr>
Add.h:<wbr></wbr>
#ifndef _ADD_H_<wbr></wbr>
#define _ADD_H_<wbr></wbr>
int Add(int x, int y);<wbr></wbr>
#endif<wbr></wbr>
使用如下 Makefile(其中红色路径需要按环境修改):
ANDROID_PATH =/home/rock/SV8860_SDK_v0.92/Source/skydroid1.6<wbr></wbr>
TOOLCHAIN_PATH =<wbr></wbr>
$(ANDROID_PATH)/platform/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin<wbr></wbr>
CFLAGS =<wbr></wbr>
-I$(ANDROID_PATH)/platform/development/ndk/build/platforms/android-4/arch-ar
m/usr/include<wbr></wbr>
LDFLAGS =<wbr></wbr>
-L$(ANDROID_PATH)/platform/development/ndk/build/platforms/android-4/arch-ar
m/usr/lib<wbr></wbr>
CC = $(TOOLCHAIN_PATH)/arm-eabi-gcc<wbr></wbr>
LD = $(TOOLCHAIN_PATH)/arm-eabi-ld<wbr></wbr>
all:<wbr></wbr>
<wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px">$(CC) -O2-fPIC -c $(CFLAGS) $(LDFLAGS) Add.c -olibadd.o</span><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px">$(LD) -olibadd.so libadd.o -shared</span><wbr><span style="font-size:18px"></span><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
clean:<wbr></wbr>
<wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px">rm -rflibadd.o</span><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px">rm -rflibadd.so 编译成动态库 libadd.so,用来模拟第三方动态库</span></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
2、封装原动态库
原动态库文件不包含 jni 接口需要的信息,所以我们需要对其进行封装,所以我
们的需求是:将 libadd.so 里面的 API 封装成带 jni 接口的动态库 libaddjni.so,步
骤如下:
A) 新建一个 Android 工程:com.android.libjni,其默认生成的 APK 运行结果是:
B) 在这个工程中新建一个 java 类,其中包含封装后的 API 函数,生成 jni 格式
的头文件(.h)
LibJavaHeader.java:
package com.android.libjni;<wbr></wbr>
public class LibJavaHeader {<wbr></wbr>
<wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> public native int Add(intx, int y);</span><wbr></wbr></wbr></wbr>
<wbr><span style="font-size:18px">{</span></wbr>
在命令行中进入该工程的 src 目录
运行如下命令
> javaccom\android\libjni\LibJavaHeader.java
> javah com.android.libjni.LibJavaHeader
此时在 src 目录下生成了一个名为 com_android_libjni_LibJavaHeader.h的头文件,
其内容如下:
com_android_libjni_LibJavaHeader.h:<wbr></wbr>
<wbr></wbr>
#include<jni.h><wbr></wbr>
<wbr></wbr>
#ifndef_Included_com_android_libjni_LibJavaHeader<wbr></wbr>
#define_Included_com_android_libjni_LibJavaHeader<wbr></wbr>
#ifdef __cplusplus<wbr></wbr>
extern "C" {<wbr></wbr>
#endif<wbr></wbr>
<wbr><span style="font-size:18px">*/</span></wbr>
* Class: <wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px">com_android_libjni_LibJavaHeader</span><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
* Method: <wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px">Add</span><wbr></wbr></wbr></wbr></wbr></wbr>
* Signature: (II)I<wbr></wbr>
<wbr></wbr>
@Override
public void onCreate(Bundle savedInstanceState){<wbr></wbr>
<wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px">super.onCreate(savedInstanceState);</span><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
int iResult = new LibJavaHeader().Add(5,6);<wbr></wbr>
TextView tv = new TextView(this);<wbr></wbr>
tv.setText(Integer.toString(iResult));<wbr></wbr>
setContentView(tv);<wbr></wbr>
<wbr><span style="font-size:18px">{ </span><wbr><span style="font-size:18px"></span><wbr></wbr></wbr></wbr>
<wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"></span><wbr></wbr></wbr></wbr></wbr>
static
<wbr><span style="font-size:18px">} </span><wbr><span style="font-size:18px"></span><wbr></wbr></wbr></wbr>
System.loadLibrary("addjni");<wbr></wbr>
<wbr><span style="font-size:18px">{</span></wbr>
{
3、编写库的封装函数 libaddjni.c<wbr></wbr>
根据前面生成的 com_android_libjni_LibJavaHeader.h 文件,编写libaddjni.c,用
来生成 libaddjni.so<wbr></wbr>
libaddjni.c:<wbr></wbr>
#include<jni.h><wbr></wbr>
#include "Add.h"<wbr></wbr>
#ifdef __cplusplus<wbr></wbr>
extern "C" {<wbr></wbr>
#endif<wbr></wbr>
<wbr><span style="font-size:18px">*/</span></wbr>
* Class: <wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px">com_android_libjni_LibJavaHeader * Method:</span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px">Add</span><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
* Signature: (II)I<wbr></wbr>
<wbr><span style="font-size:18px">/*</span></wbr>
JNIEXPORT jint JNICALLJava_com_android_libjni_LibJavaHeader_Add<wbr></wbr>
<wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px">(JNIEnv*pJE, jobject jo, jint jiX, jint jiY)</span><wbr></wbr></wbr></wbr></wbr>
<wbr><span style="font-size:18px">}</span></wbr>
<wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"></span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px"> </span><wbr><span style="font-size:18px">returnAdd(jiX, jiY);</span><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><span style="font-size:18px">{</span></wbr>
#ifdef __cplusplus<wbr></wbr>
<wbr><span style="font-size:18px">{</span></wbr>
#endif<wbr></wbr>
在 Android 源码的 platform/external新建一个文件夹 libaddjni,将libaddjni.c、Add.h
放入该目录,创建 Android.mk,内容如下:
LOCAL_PATH:= $(call my-dir)<wbr></wbr>
include $(CLEAR_VARS)<wbr></wbr>
LOCAL_PRELINK_MODULE := false<wbr></wbr>
LOCAL_SRC_FILES := libaddjni.c<wbr></wbr>
LOCAL_SHARED_LIBRARIES := libadd<wbr></wbr>
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)<wbr></wbr>
LOCAL_MODULE := libaddjni<wbr></wbr>
include $(BUILD_SHARED_LIBRARY)<wbr></wbr>
然 后 将 libadd.so 拷 贝 到 out/target/product/generic/obj/lib和
out/target/product/generic/system/lib 目 录中 , 在 platform 目 录下运行make<wbr></wbr>
libaddjni 编译之后会产生一个out/target/product/generic/obj/lib/libaddjni.so
4、开始测试
#adb push libaddjni.so /system/lib<wbr></wbr>
#adb push libadd.so /system/lib<wbr></wbr>
然后在 eclipse 运行 andro
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值