一、无参无返回值
Java代码:
package com.lvshitech.javaandc;
public class MainCls {
// 无参无返回值
public native void sayHello();
}
C++:(如果不会编写这个C++程序,就使用Java语言编写,然后自动编译生成这个.h文件再拷贝进来,具体操作方法见:http://www.cnblogs.com/josephcnblog/articles/7771848.html)
#include
#include "com_lvshitech_javaandc_MainCls.h"
#include
#include
#include
using namespace std;
// 无参无返回值的C++本地方法
JNIEXPORT void JNICALL Java_com_lvshitech_javaandc_MainCls_sayHello(JNIEnv *env, jobject obj)
{
cout << "Java调用无参无返回值的C++本地方法" << endl;
}
Java测试代码:
package com.lvshitech.javaandc;
public class MainCls {
// 无参无返回值
public native void sayHello();
// 测试
public static void main(String[] args) {
// 加载本地动态库
System.loadLibrary("JavaAndC");
// 创建MainCls类对象
MainCls mainCls = new MainCls();
// 调用本地C++动态库方法
mainCls.sayHello();
}
}
执行:
二、无返回值有简单形参
(1)int 类型
Java代码:
package com.lvshitech.javaandc;
public class MainCls {
// int类型的参数无返回值
public native void sayHello(int num);
}
C++代码:
#include
#include "com_lvshitech_javaandc_MainCls.h"
#include
#include
#include
using namespace std;
// 无参无返回值的C++本地方法
JNIEXPORT void JNICALL Java_com_lvshitech_javaandc_MainCls_sayHello(JNIEnv *env, jobject obj, jint num)
{
cout << "Java调用int类型的参数无返回值的C++本地方法:num = " << num << endl;
}
Java测试代码:
package com.lvshitech.javaandc;
public class MainCls {
// int类型的参数无返回值
public native void sayHello(int num);
// 测试
public static void main(String[] args) {
// 加载本地动态库
System.loadLibrary("JavaAndC");
// 创建MainCls类对象
MainCls mainCls = new MainCls();
// 调用本地C++动态库方法
mainCls.sayHello(100);
}
}
执行:
(2)int[] 数组类型
Java代码:
package com.lvshitech.javaandc;
public class MainCls {
// int[]数组类型的参数无返回值
public native void sayHello(int ... num);
}
C++代码:
#include
#include
#include "com_lvshitech_javaandc_MainCls.h"
#include
#include
#include
using namespace std;
// 无参无返回值的C++本地方法
/*
JNIEnv *env,代表了 Java 虚拟机 Java VM,代表了 Java 的环境,通过指针 *env 可以对 Java 端代码进行操作,是Java和本地语言(比如C++)通信的桥梁,
例如,创建Java类中的对象,调用Java对象的方法,获取Java对象中的属性等等,
JNIEnv 的指针会被 JNI 传入到本地方法的实现函数中来对Java端的代码进行操作。查看 JNIEnv 可以看到各种各样的方法
*/
JNIEXPORT void JNICALL Java_com_lvshitech_javaandc_MainCls_sayHello(JNIEnv *env, jobject obj, jintArray dat)
{
cout << "Java调用int[]数组类型的参数无返回值的C++本地方法:" << endl;
// 声明数组指针
jint *arr;// 本地类型的jint对应java类型的int,其他类型请查看数据类型映射表
arr = (env)->GetIntArrayElements(dat, false);// 从虚拟机的环境变量env中获取传递过来的数组dat并赋值给数组指针
if (!arr)
{
cout << "数组为空!" << endl;
}
else
{
// 遍历数组
for (int i = 0; i < 5; i++)
{
cout << i + 1 << " : " << arr[i] << endl;
}
}
// 释放资源
(env)->ReleaseIntArrayElements(dat, arr, 0);
}
Java测试代码:
package com.lvshitech.javaandc;
public class MainCls {
// int[]数组类型的参数无返回值
public native void sayHello(int ... num);
// 测试
public static void main(String[] args) {
// 加载本地动态库
System.loadLibrary("JavaAndC");
// 创建MainCls类对象
MainCls mainCls = new MainCls();
// 调用本地C++动态库方法
int num[] = {10, 11, 12, 13, 14};
mainCls.sayHello(num);
}
}
执行:
改变数组大小:int num[] = {10, 11, 12, 13, 14, 15, 16};
输出和上面一样,减少数组大小:int num[] = {10, 11, 12};
输出:
(3)返回 int,无形参
Java代码:
package com.lvshitech.javaandc;
public class MainCls {
// 返回 int,无形参
public native int sayHello();
}
C++代码:
#include
#include "com_lvshitech_javaandc_MainCls.h"
#include
#include
#include
using namespace std;
// 返回 int,无形参(JNIEnv *env, jobject obj,是Java环境自带的形参,这里说的是用户自己传入的形参)
JNIEXPORT jint JNICALL Java_com_lvshitech_javaandc_MainCls_sayHello(JNIEnv *env, jobject obj)
{
return 100;
}
Java测试代码:
package com.lvshitech.javaandc;
public class MainCls {
// 返回 int,无形参
public native int sayHello();
// 测试
public static void main(String[] args) {
// 加载本地动态库
System.loadLibrary("JavaAndC");
// 创建MainCls类对象
MainCls mainCls = new MainCls();
// 调用本地C++动态库方法
int ret = mainCls.sayHello();
System.out.println("调用C++本地方法返回的值:" + ret);
}
}
执行:
(4)有返回值(int[]),有形参(int[])
Java代码:
package com.lvshitech.javac;
public class MainCls {
public native int[] sayHello(int ... inArr);
}
C++代码:
#include
// 导入有关JNI的库文件以及Java函数生成的本地.h文件
#include "com_lvshitech_javac_MainCls.h"
#include
#include
#include
using namespace std;
/*
inArr:Java传入的int类型的数组
返回:jintArray,int类型的数组
实现数组元素 +10 的操作
*/
JNIEXPORT jintArray JNICALL Java_com_lvshitech_javac_MainCls_sayHello
(JNIEnv *env, jobject obj, jintArray inArr)
{
// 获取传入的数组大小
jsize inArrLen = env->GetArrayLength(inArr);
// 如果数组为空数组,则直接结束
if (inArrLen == 0)
{
return NULL;
}
// 声明一个jint*类型的指针变量,用以接收传入的数组,遍历数组+10操作
jint* tmp = env->GetIntArrayElements(inArr, false);
for (int i = 0; i < inArrLen; i++)
{
tmp[i] += 10;
}
// 创建一个jintArray的空数组,用以接收+10后的新数组元素
jintArray retArr = env->NewIntArray(inArrLen);
// 接收新数组元素,SetIntArrayRegion(空数组,数组起始下标,数组大小,新数组指针变量)
env->SetIntArrayRegion(retArr, 0, inArrLen, tmp);
// 释放资源
env->ReleaseIntArrayElements(inArr, tmp, 0);
// 返回数组
return retArr;
}
测试代码:
package com.lvshitech.javac;
public class MainCls {
public native int[] sayHello(int ... inArr);
public static void main(String[] args) {
System.loadLibrary("demo");
MainCls mcls = new MainCls();
int[] inArr = {-14, 2, 34, 5, 1, 89};
int[] retArr = mcls.sayHello(inArr);
if(retArr != null && retArr.length > 0) {
for (int i=0; i
System.out.println((i+1) + " : " + retArr[i]);
}
} else {
System.out.println("JNI返回的数组长度为0");
}
}
}
执行: