android JNI 系列 一

本文介绍一下用ndk实现jni的方式。

 静态注册函数

1. 下载linux版的ndk,windows配环境好像有点麻烦,所以就不说了

 

2. 配置NDK环境变量:

a.sudo gedit ~/.bashrc

b.在文件中输入如下的内容:

NDKROOT=/home/username/android/ndk/android-ndk-r8
export NDKROOT;

c.更新一下环境配置:source ~/.bashrc

 

4.创建一个android项目,例子如下:

 

5. 编译该android工程,目的是为了在bin下面生成class文件

6. 在项目根目录输入: javah -classpath <bin下面类包的根目录> -d jni org.eshock.jnitest.JNITest, 此时会在项目根目的jni文件夹下生成一个org_eshock_jnitest_JNITest.h 文件,

内容如下:

7.在jni目录手机创建相应的cpp文件,代码如下:

 

8. 在jni文件夹下编写Android.mk文件,内容如下:

9. 把整个项目文件夹拷到ndk/samples/下面。

10. 进入到ndk/samples/<projectname>/ 下,然后输入 $NDKROOT/ndk-build <module name>

11. 它会在ndk/samples/<projectname>/下生成obj/local/armeabi/lib***.so 

 

动态注册函数

加Java定义如下:

class Test{

private native int add(int a, int b);

}

 

1. JNI在加载时,会调用JNI_OnLoad,而卸载时会调用JNI_UnLoad,所以我们可以在JNI_OnLoad里面注册我们的native函数

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
	JNIEnv* env = NULL;
	jint result = -1;

	if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK){
		LOGE("ERROR:GetEnv failed\n");
		goto bail;
	}

	assert(env != NULL);

	if (register_native_function(env) < 0) {
		LOGE("ERROR: Boa Server native registration failed");
		goto bail;
	}

	result = JNI_VERSION_1_4;

bail:
	return result;
}

2. 自已定义register_native_function函数

int register_ckt_BehaviorManager(JNIEnv *env){
	return jniRegisterNativeMethods(env, "com/lht/Test",
			gMethods, NELEM(gMethods));
}

jniRegisterNativeMethods是JNI注册函数,"com/lht/Test"是对应的Java类,gMethods是一个Java和Native方法对应的数据结构。

typedef struct {
    const char* name; //Java中申明的Native函数名称
    const char* signature; //函数描述,这个具体的写法在以后的篇章里会定义
    void*       fnPtr; //Natvie函数指针
} JNINativeMethod;

3. 定义JNINativeMethod

static JNINativeMethod gMethods[] = {
		{"add", "(II)I", (void*)com_lht_Test_add},
};

4. 实现add函数:

jint com_lht_Test_add(JNIEnv *env, jobject clazz, jint a, jint b){ return (a + b); }

5.Makefile定义

以下方式是用NDK编译的方式

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
# 添加代码文件
LOCAL_SRC_FILES:= \
    com_lht_Test.cpp
# 添加头文件
LOCAL_C_INCLUDES += \
	$(JNI_H_INCLUDE) \
# 添加相关库文件
LOCAL_SHARED_LIBRARIES := \
	libur \
	libcutils \
# 生成的目标so名称
LOCAL_MODULE := libTest_jni

LOCAL_MODULE_TAGS := optional

include $(BUILD_SHARED_LIBRARY)


 

NDK_stack

追踪出问题代码的行数

源码:

#include "com_example_testjni_MainActivity.h"
JNIEXPORT jint JNICALL Java_com_example_testjni_MainActivity_add
(JNIEnv *env, jobject c, jint a, jint b)
{
    char *str = "abc\n";
    str[4] = 8;
    return (a + b);
}


F/libc    (14337): Fatal signal 11 (SIGSEGV) at 0x752cb0fc (code=2), thread 14337 (example.testjni)
I/DEBUG   (  263): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (  263): Build fingerprint: 'eng/debug,test-keys'
I/DEBUG   (  263): Revision: '115'
I/DEBUG   (  263): pid: 14337, tid: 14337, name: example.testjni  >>> com.example.testjni <<<
I/DEBUG   (  263): signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 752cb0fc
I/DEBUG   (  263):     r0 00000008  r1 752cb0f8  r2 00000003  r3 00000005
I/DEBUG   (  263):     r4 6d8b9438  r5 415e68f8  r6 00000004  r7 41535ca0
I/DEBUG   (  263):     r8 be9b42b8  r9 41535c98  sl 415e6908  fp be9b42cc
I/DEBUG   (  263):     ip 752c9bb9  sp be9b42b8  lr 41607450  pc 752c9bbe  cpsr 000b0030
I/DEBUG   (  263):     d0  6d6178652f6d6f63  d1  747365742f656c70
I/DEBUG   (  263):     d2  6e69614d2f696e6a  d3  7974697669746341
I/DEBUG   (  263):     d4  0000000000000000  d5  0000000000000000
I/DEBUG   (  263):     d6  0000000000000000  d7  4140000000000000
I/DEBUG   (  263):     d8  0000000000000000  d9  0000000000000000
I/DEBUG   (  263):     d10 0000000000000000  d11 0000000000000000
I/DEBUG   (  263):     d12 0000000000000000  d13 0000000000000000
I/DEBUG   (  263):     d14 0000000000000000  d15 0000000000000000
I/DEBUG   (  263):     d16 41ad6c7041abbf68  d17 41ac50d041ad1770
I/DEBUG   (  263):     d18 000000010000012e  d19 000000010000016d
I/DEBUG   (  263):     d20 00000001000012dc  d21 00000001000014eb
I/DEBUG   (  263):     d22 00000001000014fa  d23 00000001000014fc
I/DEBUG   (  263):     d24 0000000000000000  d25 0000000000000000
I/DEBUG   (  263):     d26 0000000000000000  d27 8080808080808080
I/DEBUG   (  263):     d28 0100010001000100  d29 0100010001000100
I/DEBUG   (  263):     d30 8080808080808080  d31 8080808080808080
I/DEBUG   (  263):     scr 60000010
I/DEBUG   (  263): 
I/DEBUG   (  263): backtrace:
I/DEBUG   (  263):     #00  pc 00000bbe  /data/app-lib/com.example.testjni-1/libjnitest.so (Java_com_example_testjni_MainActivity_add+5)
I/DEBUG   (  263):     #01  pc 0002044c  /system/lib/libdvm.so (dvmPlatformInvoke+112)
I/DEBUG   (  263):     #02  pc 000512b3  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+398)
I/DEBUG   (  263):     #03  pc 0003b83d  /system/lib/libdvm.so (dvmCheckCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+8)
I/DEBUG   (  263):     #04  pc 00052cb5  /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+184)
I/DEBUG   (  263):     #05  pc 000298e0  /system/lib/libdvm.so
I/DEBUG   (  263):     #06  pc 00030e30  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)
I/DEBUG   (  263):     #07  pc 0002e4c8  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
I/DEBUG   (  263):     #08  pc 00063a11  /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+392)
I/DEBUG   (  263):     #09  pc 0006b873  /system/lib/libdvm.so
I/DEBUG   (  263):     #10  pc 000298e0  /system/lib/libdvm.so
I/DEBUG   (  263):     #11  pc 00030e30  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)
I/DEBUG   (  263):     #12  pc 0002e4c8  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
I/DEBUG   (  263):     #13  pc 0006372d  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+336)
I/DEBUG   (  263):     #14  pc 0004ce9b  /system/lib/libdvm.so
I/DEBUG   (  263):     #15  pc 0003fe05  /system/lib/libdvm.so
I/DEBUG   (  263):     #16  pc 0004fb7f  /system/lib/libandroid_runtime.so
I/DEBUG   (  263):     #17  pc 000508c5  /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, char const*)+388)
I/DEBUG   (  263):     #18  pc 0000105b  /system/bin/app_process
I/DEBUG   (  263):     #19  pc 0000e593  /system/lib/libc.so (__libc_init+50)
I/DEBUG   (  263):     #20  pc 00000d7c  /system/bin/app_process
I/DEBUG   (  263): 
I/DEBUG   (  263): stack:
I/DEBUG   (  263):          be9b4278  be9b42e0  [stack]
I/DEBUG   (  263):          be9b427c  4009d49f  /system/lib/libc.so (dlfree+50)
I/DEBUG   (  263):          be9b4280  400d6000  /system/lib/libc.so
I/DEBUG   (  263):          be9b4284  c31b3810  
I/DEBUG   (  263):          be9b4288  752e4840  
I/DEBUG   (  263):          be9b428c  00000000  
I/DEBUG   (  263):          be9b4290  00000000  
I/DEBUG   (  263):          be9b4294  00000000  
I/DEBUG   (  263):          be9b4298  00000000  
I/DEBUG   (  263):          be9b429c  c31b3810  
I/DEBUG   (  263):          be9b42a0  41aab530  /dev/ashmem/dalvik-heap (deleted)
I/DEBUG   (  263):          be9b42a4  415e68f8  [heap]
I/DEBUG   (  263):          be9b42a8  415e69a0  [heap]
I/DEBUG   (  263):          be9b42ac  416a4c38  /system/lib/libdvm.so
I/DEBUG   (  263):          be9b42b0  df0027ad  
I/DEBUG   (  263):          be9b42b4  00000000  
I/DEBUG   (  263):     #00  be9b42b8  41535c94  
I/DEBUG   (  263):          ........  ........
I/DEBUG   (  263):     #01  be9b42b8  41535c94  
I/DEBUG   (  263):          be9b42bc  00000001  
I/DEBUG   (  263):          be9b42c0  00000000  
I/DEBUG   (  263):          be9b42c4  41aab530  /dev/ashmem/dalvik-heap (deleted)
I/DEBUG   (  263):          be9b42c8  41aa3fa4  /dev/ashmem/dalvik-heap (deleted)
I/DEBUG   (  263):          be9b42cc  416382b7  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+402)
I/DEBUG   (  263):     #02  be9b42d0  41535c94  
I/DEBUG   (  263):          be9b42d4  7528331e  /data/dalvik-cache/data@app@com.example.testjni-1.apk@classes.dex
I/DEBUG   (  263):          be9b42d8  752c9bb9  /data/app-lib/com.example.testjni-1/libjnitest.so (Java_com_example_testjni_MainActivity_add)
I/DEBUG   (  263):          be9b42dc  415e6908  [heap]
I/DEBUG   (  263):          be9b42e0  752e5b68  
I/DEBUG   (  263):          be9b42e4  752e5b70  
I/DEBUG   (  263):          be9b42e8  00000000  
I/DEBUG   (  263):          be9b42ec  00000000  
I/DEBUG   (  263):          be9b42f0  7179824c  
I/DEBUG   (  263):          be9b42f4  400da394  
I/DEBUG   (  263):          be9b42f8  400d6000  /system/lib/libc.so
I/DEBUG   (  263):          be9b42fc  752e5bf1  
I/DEBUG   (  263):          be9b4300  752e5bf1  
I/DEBUG   (  263):          be9b4304  752e5b70  
I/DEBUG   (  263):          be9b4308  752e5bc0  
I/DEBUG   (  263):          be9b430c  00000000  
I/DEBUG   (  263):          ........  ........


adb logcat | $NDKROOT/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi

$NDKROOT/ndk-stack -sym obj/local/armeabi/ -dump exception.log


********** Crash dump: **********
Build fingerprint: ‘test-keys'
pid: 14337, tid: 14337, name: example.testjni  >>> com.example.testjni <<<
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 752cb0fc
Stack frame #00  pc 00000bbe  /data/app-lib/com.example.testjni-1/libjnitest.so (Java_com_example_testjni_MainActivity_add+5): Routine Java_com_example_testjni_MainActivity_add at /home/luohaitao/work/android/ndk/android-ndk-r9d/samples/testJNI/jni/com_example_testjni_MainActivity.cpp:6
Stack frame #01  pc 0002044c  /system/lib/libdvm.so (dvmPlatformInvoke+112)
Stack frame #02  pc 000512b3  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+398)
Stack frame #03  pc 0003b83d  /system/lib/libdvm.so (dvmCheckCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+8)
Stack frame #04  pc 00052cb5  /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+184)
Stack frame #05  pc 000298e0  /system/lib/libdvm.so
Stack frame #06  pc 00030e30  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)
Stack frame #07  pc 0002e4c8  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
Stack frame #08  pc 00063a11  /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+392)
Stack frame #09  pc 0006b873  /system/lib/libdvm.so
Stack frame #10  pc 000298e0  /system/lib/libdvm.so
Stack frame #11  pc 00030e30  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)
Stack frame #12  pc 0002e4c8  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
Stack frame #13  pc 0006372d  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+336)
Stack frame #14  pc 0004ce9b  /system/lib/libdvm.so
Stack frame #15  pc 0003fe05  /system/lib/libdvm.so
Stack frame #16  pc 0004fb7f  /system/lib/libandroid_runtime.so
Stack frame #17  pc 000508c5  /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, char const*)+388)
Stack frame #18  pc 0000105b  /system/bin/app_process
Stack frame #19  pc 0000e593  /system/lib/libc.so (__libc_init+50)
Stack frame #20  pc 00000d7c  /system/bin/app_process


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值