关于c和cpp实现native方法的一些注释:

1>  在jni.h中首先定义了C的实现方式,然后用内联函数实现了Cpp的实现方式,如下所示:

const char* GetStringUTFChars(jstring str, jboolean *isCopy)   /* 依赖于C方式实现Cpp */

{

  return functions->GetStringUTFChars(this,str,isCopy);       /* C实现方式 */

}

因此,在C中可能这样写:(*env)->GetStringUTFChars(env, str, NULL); 但在CPP中,我们必须这么写:env->GetStringUTFChars(str, NULL);

有两个主要区别:

首先 ---> cpp函数不包含参数JNIEnv* env;

其次 ---> 在cpp实现中,env直接指向包含JNI函数指针的函数表,而在c实现中,env只是指向某个位置,而该位置才包含一个指向函数表的指针,因此必须使用(*env)才能调用JNI函数。

/* jni.h中JNIEnv的定义 */

#ifdef __cplusplus

typedef JNIEnv_ JNIEnv;                                 /* cpp定义 */

#else

typedef const struct JNINativeInterface_ *JNIEnv;       /* c定义 */

#endif

2>  关于动态库的编译:

如果使用.c文件生成动态库,则使用gcc编译:

gcc -Wl,--kill-at –shared –I D:\jdk1.7.0_75\include –I D:\jdk1.7.0_75\include\win32 IntArray.c –o intarray.dll

如果使用.cpp文件生成动态库,则使用g++编译:

g++ -Wl,--kill-at –shared –I D:\jdk1.7.0_75\include –I D:\jdk1.7.0_75\include\win32 ObjectArrayTest.cpp –o objectarraytest.dll

JNI访问基本数组时与访问字符串类似,而且可以通过JNI函数SetIntArrayRegion改变基本数组的值。此外,JNI提供了一系列的Get/Release<Type>ArrayElements函数来操作基本数组,其返回/释放一个指向(元素本身或其副本)的指针,具体实现由JVM决定,比较安全,如下程序通过native方法计算int型数组的和:

 // IntArray.java
class IntArray
{
static
{
System.loadLibrary("intarray");
}
private native int SumArray(int[] arr); public static void main(String[] args)
{
IntArray p = new IntArray();
int arr[] = new int[];
for(int i = ; i < ; i++)
{
arr[i] = i;
}
int sum = p.SumArray(arr);
System.out.println("sum = " + sum);
}
} /***********************************************/
// Intarray.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class IntArray */ #ifndef _Included_IntArray
#define _Included_IntArray
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: IntArray
* Method: SumArray
* Signature: ([I)I
*/
JNIEXPORT jint JNICALL Java_IntArray_SumArray
(JNIEnv *, jobject, jintArray); #ifdef __cplusplus
}
#endif
#endif /***********************************************/
// IntArray.c
#include "IntArray.h" JNIEXPORT jint JNICALL Java_IntArray_SumArray
(JNIEnv *env, jobject obj, jintArray arr)
{
jint buf[];
jint i, sum = ;
(*env)->GetIntArrayRegion(env, arr, , , buf);
for(i = ; i < ; i++)
{
sum += buf[i];
}
return sum;
}

JNI访问对象数组时使用函数对:Get/SetObjectArrayElement返回/更新指定索引的对象,如下native方法返回一个5*5的二维数组:

 //ObjectArrayTest.java
class ObjectArrayTest
{
static
{
System.loadLibrary("objectarraytest");
}
private static native int[][] InitInt2DArray(int size); public static void main(String[] args)
{
int[][] int2DArr = InitInt2DArray();
for(int i = ; i < ; i++)
{
for(int j = ; j < ; j++)
{
System.out.println(int2DArr + " ");
}
System.out.println();
}
}
} /***********************************************/
// ObjectArrayTest.h
class ObjectArrayTest
{
static
{
System.loadLibrary("objectarraytest");
}
private static native int[][] InitInt2DArray(int size); public static void main(String[] args)
{
int[][] int2DArr = InitInt2DArray();
for(int i = ; i < ; i++)
{
for(int j = ; j < ; j++)
{
System.out.println(int2DArr + " ");
}
System.out.println();
}
}
} /***********************************************/
// ObjectArrayTest.cpp
#include "ObjectArrayTest.h" JNIEXPORT jobjectArray JNICALL Java_ObjectArrayTest_InitInt2DArray
(JNIEnv *env, jclass cls, jint size)
{
jobjectArray result;
int i;
jclass intArrCls = env->FindClass("[I");         /* "[I" 代表int[] */
if(intArrCls == NULL)
{
return NULL;
}
result = env->NewObjectArray(size, intArrCls, NULL);  /* result是一个对象数组,其中的元素类型为int[] */
if(result == NULL)
{
return NULL;
} for(i = ; i < size; i++)
{
jint temp[];
int j;
jintArray intArr = env->NewIntArray(size);     /* 创建size个int元素的一维数组 */
if(intArr = NULL)
{
return NULL;
}
for(j = ; j < size; j++)
{
temp[j] = i + j;
}
env->SetIntArrayRegion(intArr, , size, temp); /* 将temp中的内容复制到intArr中 */
env->SetObjectArrayElement(result, i, intArr); /* 将intArr中的内容复制到result中以便返回 */
env->DeleteLocalRef(intArr);
}
return result;
}

2 通过JNI混合使用Java和C++ -----> 访问数组的更多相关文章

  1. 1 通过JNI混合使用Java和C++ -----> 操作字符串

    JNI(Java Native Interface)是Java语言的一部分,可以访问非Java语言编写的程序,也可以用于在C++程序中执行Java代码. 步骤: 1>  编写带有native声明 ...

  2. Android NDK开发之Jni调用Java对象

    https://my.oschina.net/zhiweiofli/blog/114064 通过使用合适的JNI函数,你可以创建Java对象,get.set 静态(static)和 实例(instan ...

  3. android 学习随笔二十七(JNI:Java Native Interface,JAVA原生接口 )

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

  4. NDK(19)简单示例:ndk调用java基本方法、数组;使用stl、访问设备

    一.ndk调用java类示例 1,调用基本方法 /* * Class: com_example_ndksample_MainActivity * Method: ndkFindJavaClass * ...

  5. Android NDK开发 JNI操作java构造方法,普通方法,静态方法(七)

    Android NDK开发 JNI操作java普通.静态.构造方法 1.Jni实例化一个Java类的实例jobject 1.通过FindClas( ),获取Java类的的jclass 2.通过GetM ...

  6. [转]ANDROID JNI之JAVA域与c域的互操作

    本文讲述AndroidJava域与C域互操作:Java域调用c域的函数:c域访问Java域的属性和方法:c域生成的对象的保存与使用.重点讲解c域如何访问Java域. 虽然AndroidJNI实现中,c ...

  7. JNI(Java Native Interface)

    一.JNI(Java Native Interface)        1.什么是JNI:               JNI(Java Native Interface):java本地开发接口   ...

  8. android jni与java之间数据传输时怎么转换

    1.c中的jstring数据类型就是java传入的String对象,经过jni函数的转化就能成为c的char*. Java 类型 本地c类型 说明 boolean jboolean 无符号 8 位 b ...

  9. 通过JNI实现java调用C代码和C代码调用java的代码

    一.java调用C代码 1)java中需要声明调用的函数,也就是native方法,并通过System.LoadLibrary来调用dll或者so(C代码).实例代码如下: public class H ...

随机推荐

  1. TCP/IP详解学习笔记(3)-- IP:网际协议

    1.概述      IP是TCP/IP协议族中最为核心的协议.所有的TCP,UDP,ICMP,IGMP数据都以IP数据报格式传输.      IP提供不可靠,无连接的数据报传送服务. 不可靠:它不能保 ...

  2. javascript设计模式-组合模式

    组合模式所要解决的问题: 可以使用简单的对象组合成复杂的对象,而这个复杂对象有可以组合成更大的对象.可以把简单这些对象定义成类,然后定义一些容器类来存储这些简单对象. 客户端代码必须区别对象简单对象和 ...

  3. Retrofit入门

    1 Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(ScalarsConverterFactory.create()) ...

  4. 如何初始化一个iOS原生地图

    /** 初始化一个mapView  需导入 #import <MapKit/MapKit.h> - returns: 返回一个mapView对象 */ mapView = [[MKMapV ...

  5. [drp 3]读取Xml配置文件,连接数据库

    导读:之前看一本XML的书,里面说到了对于XML的操作问题,但由于各方面的原因,一直没有总结.这次借着做项目,就总结总结对于XML文件的利用.主要是从配置数据库连接和保存数据这两方面来的.这篇博客介绍 ...

  6. Shell的概念

    Linux系统分为三个重要部分: 1:kernel(核心) 2:Shell 3:应用程序和工具

  7. JS 中 this 关键字详解

    本文主要解释在JS里面this关键字的指向问题(在浏览器环境下). 首先,必须搞清楚在JS里面,函数的几种调用方式: 普通函数调用 作为方法来调用 作为构造函数来调用 使用apply/call方法来调 ...

  8. Android IOS WebRTC 音视频开发总结(二十)-- 自由职业

    咋看标题感觉与WebRTC和音视频无关,其实有着很大的关联,文章来自博客园RTC.Blacker,转载请说明出处. 背景: 一方面因为对开发人员比较了解,不喜欢约束,喜欢自由自在,所以我们向往自由职业 ...

  9. 破解Demo

    需要破解的程序界面如下: 需要破解的程序的主要代码如下: void CEasyCrackMeDlg::OnBnClickedButtonOk() { // TODO: 在此添加控件通知处理程序代码 T ...

  10. zedboard上移植OPENCV库

    zedboard上移植OPENCV库 之前做了很多移植OPENCV库的工作,但是需要包含的各种库,需要交叉编译,X264 ,JPGE ,FFMPGE等等 注意:在<嵌入式系统软硬件协同设计实战指 ...