封装 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. SSIS结合BCP及SQL Server作业实现定时将数据导出打包实现数据同步

    首先这个流程要实现的功能大致是: 有两台服务器,一台是对外网开发的,一台是内网的.那么很明显数据交互都是外网服务器在做,而这个流程要做的就是要将外网上面的数据定时同步到内网中. 我们依对其中某张表的操 ...

  2. socket的NIO操作

    一.前言 Java中直接使用socket进行通信的场景应该不是很多,在公司的一个项目中有这种需求,所以根据自己的理解和相关资料的参考,基于NIO 实现了一组工具类库,具体的协议还未定义,后续再整理 二 ...

  3. 使用ROW_NUMBER进行的快速分页

    DECLARE @pageSize INT ; DECLARE @pageIndex INT ; SET @pageSize = 5 SET @pageIndex =2 ; --第二页,每页显示5条数 ...

  4. C++ -windows与unix路径分隔符

    文件路径中通常使用正斜杠和反斜杠 在Windows中 C++中“\\”是一种转义字符,他表示一个‘\’,就像\n表示回车一样.所以C++中的路径名: D:\matcom45\doc\users\_th ...

  5. Visual C++ 打印编程技术-内存设备环境

    1.内存设备环境 内存设备环境是一个没有设备与它联系的环境.一般利用与某个标准设备环境兼容的内存设备环境把一个位图复制到屏幕上去.为此可以先创建一个与某个标准设备环境兼容的内存设备环境,然后把所要显示 ...

  6. OC加强-day06

    #program mark - 08 NSMutableDictionary的使用 [掌握] "/08 NSMutableDictionary的使用/1_练习 "练习 1.小明的身 ...

  7. AFNetworking3.0+MBProgressHUD二次封装,一句话搞定网络提示

    对AFNetworking3.0+MBProgressHUD的二次封装,使用更方便,适用性非常强: 一句话搞定网络提示: 再也不用担心网络库更新后,工程要修改很多地方了!网络库更新了只需要更新这个封装 ...

  8. UVA 11078 Open Credit System(扫描 维护最大值)

    Open Credit System In an open credit system, the students can choose any course they like, but there ...

  9. Codevs 1689 建造高塔

    1689 建造高塔 时间限制: 1 s 空间限制: 128000 KB 题目等级 : **钻石 Diamond** 题目描述 Description n有n种石块,石块能无限供应.每种石块都是长方体, ...

  10. Codevs 1074 食物链 2001年NOI全国竞赛

    1074 食物链 2001年NOI全国竞赛 时间限制: 3 s 空间限制: 64000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description 动物王国中有三类动物 A,B ...