JNI中的java类参数传递

原创 2015年11月17日 21:36:46

在com.example.test中有两个类javaclass1.java和javaclass2.java,这两个是native的传递参数类型,下面说说如何将这样的参数类型从java传递到jni中,又如何冲jni传递到C中。

jni的java接口文件:

public class testJNI {
	public static final int a = 0;
	public static final int b = 1;
	public static final int c = 2;
	public static final int d = 3;

	public native int function1(javaclass1 param_in);
	public native int function2(javaclass2 param_in);	

	static {
	System.loadLibrary("exampleJNI");
	}	
}

下面以fuction1为例说明java类参数如何传递:
<pre name="code" class="cpp">JNIEXPORT jint JNICALL Java_com_example_test_function1(JNIEnv *env, jobject obj, jobject objp)
{

	javaclass1 param_in;
	int flag = 0;
	jclass objClass = (*env)->FindClass(env, "com/example/test/javaclass1");//这里必须直接指明参数类型
	jfieldID membername1 = (*env)->GetFieldID(env, objClass, "member1", "I");
	jfieldID membername2 = (*env)->GetFieldID(env, objClass, "member2", "I");
	jfieldID membername3 = (*env)->GetFieldID(env, objClass, "member3", "I");
	jfieldID membername4 = (*env)->GetFieldID(env, objClass, "member4", "I");
	jint membervalue1 = (*env)->GetIntField(env, objp, membername1);
	jint membervalue2 = (*env)->GetIntField(env, objp, membername2);
	jint membervalue3 = (*env)->GetIntField(env, objp, membername3);
	jint membervalue4 = (*env)->GetIntField(env, objp, membernane4);
	
	//将解析出来的参数打包,传递给C function
	param_in.member1 = membervalue1;
	param_in.member2 = membervalue2;
	param_in.member3 = membervalue3;
	param_in.member4 = membervalue4;
		
	handle = cfunctioncall1(¶m_in);//c 函数

	if(handle == NULL)
	{
		flag = -1;
	}

	return((jint) flag);
}



<pre name="code" class="cpp">下面说说包含数组的java类参数传递


JNIEXPORT jint JNICALL Java_com_example_test_function2(JNIEnv *env, jobject obj, jint cmd, jobject objp)
{
double* gx_data, *gy_data, *gz_data;
javaclass2 g_data;// javaclass 里面包含三个大小一样double类型的数组
jclass objClass = (*env)->FindClass(env, "com/example/testact/javaclass2");//获取参数的类型
jfieldID gx_name = (*env)->GetFieldID(env, objClass, "gx", "[D");//获取域名
jfieldID gy_name = (*env)->GetFieldID(env, objClass, "gy", "[D");
jfieldID gz_name = (*env)->GetFieldID(env, objClass, "gz", "[D");
jdoubleArray gx_objArray = (*env)->GetObjectField(env, objp, gx_name);//获取数组类型域,这个与int的成员不同,要进一步解析
jdoubleArray gy_objArray = (*env)->GetObjectField(env, objp, gy_name);
jdoubleArray gz_objArray = (*env)->GetObjectField(env, objp, gz_name);

jdouble* gx_ptr = (*env)->GetDoubleArrayElements(env, gx_objArray, NULL);//获取数据指针
jdouble* gy_ptr = (*env)->GetDoubleArrayElements(env, gy_objArray, NULL);
jdouble* gz_ptr = (*env)->GetDoubleArrayElements(env, gz_objArray, NULL);

jsize len = (*env)->GetArrayLength(env, gx_objArray);// 数组长度

gx_data = (double*)Mymalloc(len, sizeof(double));//copy到本地用的buffer
gy_data = (double*)Mymalloc(len, sizeof(double));
gz_data = (double*)Mymalloc(len, sizeof(double));

if((gx_data == NULL)||(gy_data == NULL)||(gz_data == NULL))
{
LOGE("Err! malloc memory failed! %s %d\n", __FILE__, __LINE__);
goto err;
}

memcpy(gx_data, gx_ptr, sizeof(double)*len);//copy到本地
memcpy(gy_data, gy_ptr, sizeof(double)*len);
memcpy(gz_data, gz_ptr, sizeof(double)*len);

(*env)->ReleaseDoubleArrayElements(env, gx_objArray, gx_ptr, 0);//释放,这个是必须的,切勿忘记
(*env)->ReleaseDoubleArrayElements(env, gy_objArray, gy_ptr, 0);
(*env)->ReleaseDoubleArrayElements(env, gz_objArray, gz_ptr, 0);

g_data.gx = gx_data;
g_data.gy = gy_data;
g_data.gz = gz_data;

jint ret = cfunctioncall2(handle, cmd, (unsigned int)&g_data));

Myfree(gx_data);
Myfree(gy_data);
Myfree(gz_data);

return(ret);

err:
Myfree(gx_data);
Myfree(gy_data);
Myfree(gz_data);
return((jint)(-1));
}




码字不易,转载请注明出处




JNI调用C++类的方式

本文讲解了在jni中调用c++对象的方式,并且给出了一个代码实例。
  • xiaohan2909
  • xiaohan2909
  • 2015年12月02日 21:42
  • 1547

JNI在C++与java间传递各种数据格式举例

JniMethodInfo minfo;//JniHelper    /* 测试用方法 */ bool isHave = JniHelper::getStaticMethodInfo(minfo,...
  • keven418440201
  • keven418440201
  • 2016年07月15日 14:27
  • 1123

[JNI]开发之旅(6)JNI函数中访问java类中对象的属性

JNI函数的实现在c/c++中实现的,如果想访问java中定义的类对象的实例域需要三个步骤:1.通过GetObjectClass()函数获得该对象的类class,返回值是一个jclass; 2.调用...
  • tsdfk1455
  • tsdfk1455
  • 2016年12月25日 12:28
  • 918

Android Studio下JNI编程2(接上篇,详细讲解java与c层互传参数)

Android Studio下JNI环境搭建、编译、运行等可以参考: http://blog.csdn.net/huangximin1990/article/details/50441400 ...
  • huangximin1990
  • huangximin1990
  • 2016年03月09日 00:18
  • 1101

学习android JNI的那些事儿--------6. 在java中传入引用数据类型(对象)作为参数

之前我们介绍过在java中传入一些基本数据类型作为参数在jni中的处理,这里我们来介绍下载java中传入我们自定义的一个对象作为参数。 我们先自定义一个class为student public c...
  • zhangjie201412
  • zhangjie201412
  • 2012年02月29日 13:45
  • 3218

[JNI]开发之旅(8)传递参数给JNI函数

本节将介绍在JNI编程中如何传递参数和返回值。首先要强调的是,native方法不但可以传递Java的基本类型做参数,还可以传递更复杂的类型,比如String,数组,甚至自定义的类。jni.h中定义了很...
  • tsdfk1455
  • tsdfk1455
  • 2017年01月01日 00:34
  • 1208

JNI中在被调用的C/C++函数中如何访问Java程序中的类,并编写应用实例

1、在javah工具生成的C/C++函数声明中的JNIEnv类型参数和jobject类型参数的介绍 JNIEXPORT void JNICALL Java_jni_TestNative_sayhel...
  • u011955252
  • u011955252
  • 2015年11月06日 20:45
  • 654

JNI中枚举类型作为参数

参考资料:使用JNI进行Java与C/C++语言混合编程(1)--在Java中调用C/C++本地库      java native方法及JNI实例 JNI是Java Native Int...
  • wangjie5540
  • wangjie5540
  • 2015年07月14日 14:09
  • 1108

JNI获取并修改Java中类的变量和静态变量的值

对于JNI的基本使用请移步:Hello JNI本文主要介绍以下几个函数的使用:GetObjectClassGetFieldID,GetStaticFieldIDGet< Type>Field,GetS...
  • likuan0214
  • likuan0214
  • 2016年09月24日 12:56
  • 3744

JNI学习(三)、JNI本地方法访问Java端的属性和方法

在JNI调用中,肯定会涉及到本地方法操作Java类中数据和方法。在Java1.0中“原始的”Java到C的绑定中,程序员可以直接访问对象数据域。然而,直接方法要求虚拟机暴露他们的内部数据布局,基于这个...
  • LonelyRoamer
  • LonelyRoamer
  • 2012年09月08日 16:42
  • 6770
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JNI中的java类参数传递
举报原因:
原因补充:

(最多只允许输入30个字)