封装 jni 的 java 层 Integer、Long 对象使用时必须用 new 对象的形式,防止修改 128>x x>-128 之间缓存的对象,一定要谨记

配置

在 eclipse 环境下开发 jni
1. 导入 ndk Window->Preferences->Android->NDK,点击 Browse 引入 ndk 的目录
2. 创 建 java 类 , 声 明 一 个 private native String CBBT_getVersionString();

JNIEXPORT jstring JNICALL Java_com_raiing_ABBTSurface_getVersionString(JNIEnv *env,

jobject obj)
3. 使用 javah 生成 jni 头文件.

3-a. run - external tools - external tools configuration - program - new lanch configuration
3-b. name:javah

location:jdk 安装目录中的 javah.exe 所在目录\javah.exe
Files\Java\jdk1.7.0_02\bin\javah.exe

working directory: ${workspace_loc}

arguments: -v -classpath "${project_loc}/bin/classes"
${java_type_name}

common - Display in favorites menu - 选中 External tools
中显示 javah。
3-c. apply , close
3-d. 点中 src- com.raiing - CTMProcess.java 文件

3-e. run - external tools - javah 将生成 jni 的头文件在 jni 目录下。按 F5 刷新 project
explorer 的 jni 目录。

4. 添加 Android.mk 和 Application.mk 文件到 jni 目录。
android.mk 内容:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog

LOCAL_MODULE := child 自己起的库名字

LOCAL_SRC_FILES := com_raiing_childmodule_ChildModule.cpp utilities.c
include $(BUILD_SHARED_LIBRARY)

ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
LOCAL_LDFLAGS := $(LOCAL_PATH)\ccode\armeabi-v7a\libCBBT.a
LOCAL_LDFLAGS += $(LOCAL_PATH)\ccode\armeabi-v7a\libutilities.a 两者有
顺序

比如:C:\Program
"${project_loc}/jni"

-d
以便在 run - external tools

#LOCAL_STATIC_LIBRARIES := utilities

endif

需要修改上述内容的 LOCAL_MODULE:= 为希望的库名称。生成的库名将在这个名称前增加
lib 前缀。
需要修改 LOCAL_SRC_FILES:= 将 jni 目录下的所有 cpp c 添加到后面,空格分隔。

Application.mk 内容:
APP_ABI := all 生成所有平台的目录文件,我们一般只需要三个

APP_ABI := armeabi armeabi-v7a arm64-v8a
APP_CFLAGS += -Wno-error=format-security -D_ENV_ANDROID_=1

5. 添加 ndk 编译命令到项目。
5-a. run - external tools - external tools configuration - program - new lanch configuration

main- name: ndk_build

main-location: ndk 安 装 目 录 \ndk-build.cmd
比如:S:\work_dir\android-ndk-r9d\ndk-build.cmd

main- working directory: ${workspace_loc}/${project_name}/jni
common - Display in favorites menu - 选中 External tools

5-b. 选中 CTMProcess 项目名,project - properties - builders - import - ndk_build
5-d. 在 builders 中选中 ndk_build ,点击 UP,将 ndk_build 调整到最高。

基本数据类型

Java Type Native Type Description

boolean jboolean

byte jbyte

char jchar

double jdouble

float jfloat

int jint

long jlong

short jshort

void void

8 bits, unsigned
8 bits, signed
16 bits, unsigned
64 bits

32 bits
32 bits, signed
64 bits, signed
16 bits, signed
N/A

Java Type

Signature

boolean

Z

byte

B

char

C
double

D

float

F

int

I

long

J

void

V

object

Lfully-qualified-class;
type[]

[type
method signature ( arg-types) ret-type

Method

Signature

void f1()

()V

int f2(int, long)

(IJ)I

boolean f3(int[])

([I)B

double f4(String, int)
(Ljava/lang/String;I)D
void f5(int, String [], char)
(I[Ljava/lang/String;C)V

数据交互

基本类型不需要转换,navtive 层直接可以使用,赋值到 c 里面需要强转,如 int uciT->cycleDays = (uint16) cycle_days;
uint16 表示有符号,正数 int16 无符号正负都可以

String 转换
const char *= CBBT_getVersionString();

char*转String
jstring jstrBuf = env->NewStringUTF();
String 转 char*
char *filePath = (char *)(env->GetStringUTFChars(path, NULL));
不用时需要释放
ReleaseStringUTFChars(buf, jstrBuf);

对象
有 jobject 对象

jclass cls = env->GetObjectClass(javaUCI);

创建某个类对象

jclass cls_acr = env->FindClass("com/raiing/cbbtjni/entity_jni/ACR_T");
jmethodID construct_acr = env->GetMethodID(cls_acr, "<init>", "()V");
jobject obj_acr = env->NewObject(cls_acr, construct_acr, "");

给对象某个字段赋值,首先获取字段 id,再给字段赋值
jfieldID originFieldID = env->GetFieldID(cls_acr, "origin", "I");
env->SetIntField(obj_acr, originFieldID, (jint) acrT->origin);
jfieldID extraDataFieldID = env->GetFieldID(cls, "extraData", "[B");

对象集合 ArrayList<Entity>,给集合添加对象
jclass cls_ArrayList = env->GetObjectClass(jobject);
jmethodID arrayList_add = env->GetMethodID(cls_ArrayList, "add", "(Ljava/lang/Object;)Z");

env->CallBooleanMethod(jobject, arrayList_add, obj_cbbt);
env->DeleteLocalRef(obj_cbbt);

获取集合里面的对象

jmethodID arraylist_get = env->GetMethodID(cls_arraylist, "get", "(I)Ljava/lang/Object;");
jobject obj_uci = env->CallObjectMethod(jobject, arraylist_get, i);
env->DeleteLocalRef(obj_uci);

循环操作里面一定要删除引用,否则会有 512 的限制,如:jbytearray jstring jclass jobject

数组类型数据赋值给 c 层
jbyteArray extraData = (jbyteArray) env->GetObjectField(obj,

extraDataFieldID);
int size = env->GetArrayLength(extraData);

jbyte *ed = (jbyte *) cbbt.extraData;
env->GetByteArrayRegion(, 0, size, ed);
env->DeleteLocalRef(extraData);

c 层数组赋值给 java
jbyteArray jbarray = env->NewByteArray(len);
jbyte *jb = env->GetByteArrayElements(jbarray, 0);
memcpy(jb, cbbt->extraData, len);
env->SetByteArrayRegion(jbarray, 0, len, jb);

输入输出

c
int8 ABBT_getExpectedDataRange(uint32 currentTime, int32 timeZone, uint32 *startTime,
uint32 *endTime);
java
private native int getExpectedDataRange(long currentTime, long timeZone, Long startTime,
Long endTime);

cpp
JNIEXPORT jint JNICALL Java_com_raiing_ABBTSurface_getExpectedDataRange(

JNIEnv *env, jobject obj, jlong curTime, jlong timeZone,

jobject startTime, jobject endTime)
jclass cls = env->GetObjectClass(retObject);
jmethodID codeMethodID = env->GetMethodID(cls, "<init>", "(J)V");
env->CallVoidMethod(startTime, codeMethodID, retLong);

java 层错误的写法
Integer startTime = 0;
Integer endTime = 0;
两者指向的同一个内存地址,再 c 层输出修改的时候,本来输出两个值,就变为了一个

查看 ndk 崩溃 log
需要的 So 文件在 obj\local\arm64-v8a\libCBBT.so

S:\Android_SDK\ndk-bundle\toolchains
Eclipse jni 提示

异常问题
建的工程没有 c/c++ build 支持,工程右键 android tools

Log 占位符

C 语言中输入输出函数占位符介绍 :
占位符 数据类型

%d

int
%ld

long int

%c

char

%f

float

&lf

double

%x

十六进制

%O

八进制

%s

字符串

--> Add native Support

Project Properties -> C/C++ General -> Path and Symbols

选择 include 标签,

Add -> $Android_NDK_HOME/platforms/android-14/arch-arm/usr/include 任意版本

选中 All languages.

最后 Apply -> OK

Log 测试不能输出 long uint64,需要分解为 uint32
LOGV("java2SYMPTOM->UEI_SYMPTOM_T 结构体 111: symptomTypeH jj

h:%u,l:%u", (uint32)(symptomTypeH>>32),(uint32)(symptomTypeH));

学习网址

http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html
http://home.pacifier.com/~mmead/jni/cs510ajp/index.html#JNI Data Types

http://blog.csdn.net/woshinia/article/details/25132353

http://blog.csdn.net/u012690435/article/details/38612461 参数传递
http://mysuperbaby.iteye.com/blog/1603817 DeleteLocalRef 问题

http://www.oschina.net/question/2241352_213433 addr2line 定位 jni 问题行号

jni相关的更多相关文章

  1. JNI相关笔记 [TOC]

    JNI相关笔记 目录 JNI相关笔记 1 生成native code所需要的头文件 2 JNI提供的一些函数和方法 3 局部引用,全局引用,全局弱引用. 4 异常 1 生成native code所需要 ...

  2. JNI相关使用记录

    JNI 工作流程 java层调用system.load方法. 通过classloader拿到了so文件的绝对路径,然后调用nativeload()方法. 通过linux下的dlopen方法,加载并查找 ...

  3. JNI相关知识

    JNI(Java Native Interface,JAVA原生接口) 使用JNI可以使Java代码和其他语言写的代码(如C/C++代码)进行交互. 问:为什么要进行交互? |-  首先,Java语言 ...

  4. 【译文】JNI编程

    原文链接: https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html   没有逐字翻译,解说了文章的大 ...

  5. Android开发笔记之《JNI常用知识汇总》

    参考资料: Android Studio中NDK开发 : http://www.tuicool.com/articles/NBjQnyAndroid Studio使用新的Gradle构建工具配置NDK ...

  6. cocos2d-x中的Jni使用(C++与Andriod方法互调)

    作者:何卫 转载请注明,原文链接:http://www.cnblogs.com/hewei2012/p/3376616.html 前提条件: 1.操作的游戏工程和cocos2d_x游戏引擎是一个目录的 ...

  7. 【转】 Android 开发 之 JNI入门 - NDK从入门到精通

    原文网址:http://blog.csdn.net/shulianghan/article/details/18964835 NDK项目源码地址 : -- 第一个JNI示例程序下载 : GitHub  ...

  8. 较具体的介绍JNI

    JNI事实上是Java Native Interface的简称,也就是java本地接口.它提供了若干的API实现了和Java和其它语言的通信(主要是C&C++).或许不少人认为Java已经足够 ...

  9. JNI编程(二) —— 让C++和Java相互调用(1)

    自己在外面偷偷的算了下,又有将近两个月没更新过blog了.趁着今天有兴致,来更新JNI编程的第二篇文章.在第一篇里,大概介绍了JNI的特点.用途和优劣.并且做一个最简单的JNI的例子,不过说实话那个例 ...

随机推荐

  1. python中关于正则表达式三

    2015年8月14日 11:10 7.2正则表达式操作 正则表达式使用反斜杠字符'\'来暗示一些特殊的形式或者允许特殊的字符使用但是没有调用它们特殊的意思.在字符串常量中的相同目标的字符的python ...

  2. Android开发之Handler

    我们都知道应用程序开启后,安卓会开启一个主线程(UI线程),主线程管理UI控件,进行事件分发.那为什么会出现Handler呢? 例如你要是点击一个 Button ,Android会分发事件到Butto ...

  3. [转] c# 数据类型占用的字节数

    http://www.cnblogs.com/laozuan/archive/2012/04/24/2467888.html

  4. SQL Server 脚本语句

    一.语法结构 select select_list [ into new_table ] from table_source [ where search_condition ] [ group by ...

  5. HDU 1176 免费馅饼(数字三角形)

    免费馅饼 Problem Description 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉 ...

  6. C/C++中memset函数

    本文学习参考http://baike.baidu.com/link?url=ZmSyY8ciB_nJt9KM-W2fiEFJrC2mugFsLqRdY2b4pLe8rD_jRXyN7_pj0GBBD2 ...

  7. (转)怎么去掉Xcode工程中的某种类型的警告 Implicit conversion loses integer precision: 'NSInteger' (aka 'long') to 'int32

    问题描述  在我们的项目中,通常使用了大量的第三方代码,这些代码可能很复杂,我们不敢改动他们,可是作者已经停止更新了,当sdk升级或者是编译器升级后,这些遗留的代码可能会出现许许多多的警告,那么我们有 ...

  8. centOS 6 python MySQLdb 提示 no module

    http://www.cnblogs.com/czh-liyu/archive/2012/11/30/2796028.html(转) 用python连接本地数据库时,提示no module MySQL ...

  9. tomcat server.xml配置文件 解析

      把服务拆分出来了.      前几天我也进行了拆分.可是当时服务起不来所以我想会不会有什么设置,使得这个服务在主机中只能启一个.然后我又找了一台服务器,也把代码放了进去.结果仿佛是我料想到的样子, ...

  10. Linux网络

    netstat 查看网络状态 netstat: -r :显示路由表 -n: 以数字方式显示 -u: 显示UDP连接 -t :显示TCP连接 -l:显示监听状态的连接 -p: 显示监听指定套接字的进程的 ...