[转]C++和JNI的数据转换(二)
//
返回一个结构数组,返回一个硬盘信息的结构数组
JNIEXPORT jobjectArray JNICALL Java_com_sundy_jnidemo_ChangeMethodFromJni_getStructArray
(JNIEnv
*
env, jobject _obj)
{
//申明一个object数组
jobjectArray args = 0;
//数组大小
jsize len = 5;

//获取object所属类,一般为ava/lang/Object就可以了
jclass objClass = (env)->FindClass("java/lang/Object");

//新建object数组
args = (env)->NewObjectArray(len, objClass, 0);

/* 下面为获取到Java中对应的实例类中的变量*/

//获取Java中的实例类
jclass objectClass = (env)->FindClass("com/sundy/jnidemo/DiskInfo");
//获取类中每一个变量的定义
//名字
jfieldID str = (env)->GetFieldID(objectClass,"name","Ljava/lang/String;");
//序列号
jfieldID ival = (env)->GetFieldID(objectClass,"serial","I");

//给每一个实例的变量付值,并且将实例作为一个object,添加到objcet数组中
for(int i=0; i < len; i++ )
{
//给每一个实例的变量付值
jstring jstr = WindowsTojstring(env,"我的磁盘名字是 D:");
//(env)->SetObjectField(_obj,str,(env)->NewStringUTF("my name is D:"));
(env)->SetObjectField(_obj,str,jstr);
(env)->SetShortField(_obj,ival,10);

//添加到objcet数组中
(env)->SetObjectArrayElement(args, i, _obj);
}
//返回object数组
return args;

}
全部的C/C++方法实现代码如下:
/*
*
* 一缕阳光(sundy)版权所有,保留所有权利。
*/
/**
*
* TODO Jni 中一个从Java到C/C++参数传递测试类
*
* @author 刘正伟(sundy)
* @see http://www.cnweblog.com/sundy
* @see mailto:sundy26@126.com
* @version 1.0
* @since 2005-4-30
*
* 修改记录:
*
* 日期 修改人 描述
* ----------------------------------------------------------------------------------------------
*
*
*
*/
//
JniManage.cpp : 定义 DLL 应用程序的入口点。
//
package com.sundy.jnidemo;
#include
"
stdafx.h
"

#include
<
stdio.h
>
#include
<
math.h
>
#include
"
jni.h
"
#include
"
jni_md.h
"

#include
"
./head/Base.h
"
#include
"
head/wmi.h
"
#include
"
head/com_sundy_jnidemo_ChangeMethodFromJni.h
"
//
通过javah –jni javactransfer 生成
#include
<
stdio.h
>
#include
"
stdlib.h
"
#include
"
string.h
"

#pragma comment (lib,
"
BaseInfo.lib
"
)
#pragma comment (lib,
"
jvm.lib
"
)
//
硬盘信息
struct
{
char name[256];
int serial;
}
DiskInfo;
/*BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
LPTSTR strName = new CHAR[256] ;
(*GetHostName)(strName);
printf("%s\n",strName);
delete [] strName;

return TRUE;
}*/
//
将jstring类型转换成windows类型
char
*
jstringToWindows( JNIEnv
*
env, jstring jstr );
//
将windows类型转换成jstring类型
jstring WindowsTojstring( JNIEnv
*
env,
char
*
str );

//
主函数
BOOL WINAPI DllMain(HANDLE hHandle, DWORD dwReason, LPVOID lpReserved)
{
return TRUE;
}
//
输入常用的数值类型 Boolean,Byte,Char,Short,Int,Float,Double
JNIEXPORT
void
JNICALL Java_com_sundy_jnidemo_ChangeMethodFromJni_displayParms
(JNIEnv
*
env, jobject obj, jstring s, jint i, jboolean b)
{
const char* szStr = (env)->GetStringUTFChars(s, 0 );
printf( "String = [%s]\n", szStr );
printf( "int = %d\n", i );
printf( "boolean = %s\n", (b==JNI_TRUE ? "true" : "false") );
(env)->ReleaseStringUTFChars(s, szStr );
}

//
调用一个静态方法,只有一个简单类型输出
JNIEXPORT jint JNICALL Java_com_sundy_jnidemo_ChangeMethodFromJni_add
(JNIEnv
*
env, jobject, jint a, jint b)
{
int rtn = (int)(a + b);
return (jint)rtn;
}

////输入一个数组,这里输入的是一个Boolean类型的数组
JNIEXPORT
void
JNICALL Java_com_sundy_jnidemo_ChangeMethodFromJni_setArray
(JNIEnv
*
env, jobject, jbooleanArray ba)
{
jboolean* pba = (env)->GetBooleanArrayElements(ba, 0 );
jsize len = (env)->GetArrayLength(ba);
int i=0;
// change even array elements
for( i=0; i < len; i+=2 )
{
pba[i] = JNI_FALSE;
printf( "boolean = %s\n", (pba[i]==JNI_TRUE ? "true" : "false") );
}
(env)->ReleaseBooleanArrayElements(ba, pba, 0 );
}

////返回一个字符串数组
JNIEXPORT jobjectArray JNICALL Java_com_sundy_jnidemo_ChangeMethodFromJni_getStringArray
(JNIEnv
*
env, jobject)
{
jstring str;
jobjectArray args = 0;
jsize len = 5;
char* sa[] = { "Hello,", "world!", "JNI", "is", "fun" };
int i=0;
args = (env)->NewObjectArray(len,(env)->FindClass("java/lang/String"),0);
for( i=0; i < len; i++ )
{
str = (env)->NewStringUTF(sa[i] );
(env)->SetObjectArrayElement(args, i, str);
}
return args;
}

//
返回一个结构,这里返回一个硬盘信息的简单结构类型
JNIEXPORT jobject JNICALL Java_com_sundy_jnidemo_ChangeMethodFromJni_getStruct
(JNIEnv
*
env, jobject obj)
{
/* 下面为获取到Java中对应的实例类中的变量*/

//获取Java中的实例类
jclass objectClass = (env)->FindClass("com/sundy/jnidemo/DiskInfo");

//获取类中每一个变量的定义
//名字
jfieldID str = (env)->GetFieldID(objectClass,"name","Ljava/lang/String;");
//序列号
jfieldID ival = (env)->GetFieldID(objectClass,"serial","I");


//给每一个实例的变量付值
(env)->SetObjectField(obj,str,(env)->NewStringUTF("my name is D:"));
(env)->SetShortField(obj,ival,10);
return obj;
}

//
返回一个结构数组,返回一个硬盘信息的结构数组
JNIEXPORT jobjectArray JNICALL Java_com_sundy_jnidemo_ChangeMethodFromJni_getStructArray
(JNIEnv
*
env, jobject _obj)
{
//申明一个object数组
jobjectArray args = 0;
//数组大小
jsize len = 5;

//获取object所属类,一般为ava/lang/Object就可以了
jclass objClass = (env)->FindClass("java/lang/Object");

//新建object数组
args = (env)->NewObjectArray(len, objClass, 0);

/* 下面为获取到Java中对应的实例类中的变量*/

//获取Java中的实例类
jclass objectClass = (env)->FindClass("com/sundy/jnidemo/DiskInfo");
//获取类中每一个变量的定义
//名字
jfieldID str = (env)->GetFieldID(objectClass,"name","Ljava/lang/String;");
//序列号
jfieldID ival = (env)->GetFieldID(objectClass,"serial","I");

//给每一个实例的变量付值,并且将实例作为一个object,添加到objcet数组中
for(int i=0; i < len; i++ )
{
//给每一个实例的变量付值
jstring jstr = WindowsTojstring(env,"我的磁盘名字是 D:");
//(env)->SetObjectField(_obj,str,(env)->NewStringUTF("my name is D:"));
(env)->SetObjectField(_obj,str,jstr);
(env)->SetShortField(_obj,ival,10);

//添加到objcet数组中
(env)->SetObjectArrayElement(args, i, _obj);
}
//返回object数组
return args;

}

//
将jstring类型转换成windows类型
char
*
jstringToWindows( JNIEnv
*
env, jstring jstr )
{
int length = (env)->GetStringLength(jstr );
const jchar* jcstr = (env)->GetStringChars(jstr, 0 );
char* rtn = (char*)malloc( length*2+1 );
int size = 0;
size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn,(length*2+1), NULL, NULL );
if( size <= 0 )
return NULL;
(env)->ReleaseStringChars(jstr, jcstr );
rtn[size] = 0;
return rtn;
}
color: #000
接[转]C++和JNI的数据转换(一)
下面我们来看看,如果通过使用数组和对象,从C++中的获取到Java中的DiskInfo 类对象,并返回一个DiskInfo数组:











































全部的C/C++方法实现代码如下:









































































































































































































