JNI中的类型和c语言中的类型转换

       半个月以前是打算写一些学习HTML的学习笔记的,后来想想现在网上关于HTML的学习网页这么多,就觉得没必要了。所以就不写了。

两天前,朋友找我帮忙,让我帮他实现在java中调用c语言中的函数,说白了就是做一个动态链接库(.dll)。我一看他传给我的源代码,差点吓尿啊——500多个函数啊。

可能函数多,所有遇到的类型转换比较全,我就在这里总结一下吧。

做这种借口一点都不难,无非就是数据类型匹配的问题。JNI中有很多种类型,其中的基本类型就有和c语言中的类型完全匹配的,网上有很多介绍这里就不多说了。来进入正题吧(PS:那些将.java转换成.h的方法等这里就不赘述了):

1、最常见的就是jstring和char*,之间的转换了。

1)jstring转换为char*

JNIEXPORT jint JNICALL Java_testENopen_Jepanet2_ENsaveinpfile
(JNIEnv *env, jobject _obj, jstring _str)
{
char* f1 = (*env)->GetStringUTFChars(env,_str,0);
int result = ENsaveinpfile(f1);
(*env)->ReleaseStringUTFChars(env,_str,f1);
printf("%s",f1);
return result;
}

因为我有方法实现的源码,就在实现的时候就少了很多不必要的加载和查找代码,直接调用方法ENsaveinpfile(f1)就可以了。这不是重点,重点是jstring和char*之间的转换 。通常调用过方法GetStringUTFChars()后,都要在调用方法ReleaseStringUTFChars(),不然就造成了内存的浪费。

2)char* 转换为jstring

JNIEXPORT jstring JNICALL Java_testENopen_Jepanet2_ENgetpatternid
  (JNIEnv *env, jobject _obj, jint Inum)
{
jstring _str = (jstring)malloc(sizeof(jstring));
char* result = (*env)->GetStringUTFChars(env,_str,0);
int resultcode = ENgetpatternid(Inum,result);
jstring strReturn = (*env)->NewStringUTF(env,result);
(*env)->ReleaseStringUTFChars(env,_str,result);
printf("error code:%d\n",resultcode);
return strReturn;
}

这里可能写的有点麻烦了,不过测试过了。


2、 jintArray 和 int * ( int[ ] )之间的转换(jFloatArray 和 float*, jDoubleArray 和 double*之间的转换相似)

1)int* 转成 jintArray

JNIEXPORT jintArray JNICALL Java_testENopen_Jepanet2_ENgetqualtype
  (JNIEnv *env, jobject _obj)
{
jintArray result = (*env)->NewIntArray(env,2);
int temp[2];
int resultCode = ENgetqualtype(&(temp[0]),&(temp[1]));
printf("error code:%d\n",resultCode);
(*env)->SetIntArrayRegion(env,result,0,2,temp);
return result;
}

这里NewIntArray()是初试化jintArray,方法SetIntArrayRegion()则是给jintArray result赋值。

2)jintArray转换成int*等同于jDoubleArray 和 double*之间的转换

JNIEXPORT jdouble JNICALL Java_testENopen_funcs_interp
  (JNIEnv *env, jobject _obj, jint Inum, jdoubleArray dNum1, jdoubleArray dNum2, jdoubleArray dNum3)
{
double *temp1 = (*env)->GetDoubleArrayElements(env,dNum1,0);
double *temp2 = (*env)->GetDoubleArrayElements(env,dNum2,0);
double *temp3 = (*env)->GetDoubleArrayElements(env,dNum3,0);
double result = interp(Inum,temp1,temp2,temp3);
(*env)->ReleaseDoubleArrayElements(env,dNum1,temp1,0);
(*env)->ReleaseDoubleArrayElements(env,dNum1,temp1,0);
(*env)->ReleaseDoubleArrayElements(env,dNum1,temp1,0);
return result;
}

只要换相应的方法就可以了。

3、看看最麻烦的,char** 和string[](jobjectArray)之间的转换

JNIEXPORT jint JNICALL Java_testENopen_funcs_findmatch
  (JNIEnv *env, jobject _obj, jstring _str, jobjectArray _strS)
{
jstring jstr; 
int result;
char* temp = (*env)->GetStringUTFChars(env, _str, 0);
jsize len = (*env)->GetArrayLength(env, _strS); 
int i=0;
char **pstr = (char **) malloc(len*sizeof(char *));  
for (i=0 ; i<len; i++) { 
jstr = (*env)->GetObjectArrayElement(env, _strS, i);
pstr[i] = (*env)->GetStringUTFChars(env, jstr, 0);
}
result = findmatch(temp,pstr);
for(i=0;i<len;i++)
{
jstr = (jstring)(*env)->GetObjectArrayElement(env, _strS, i);
(*env)->ReleaseStringUTFChars(env,jstr,pstr[i]);
}
return result;
}

不解释了,我看着也是醉了。。。。但是理解起来应该不难!

4、返回jobjectArray(int [][])

这里只写一些主要的方法吧(不贴原方法了,有点长):

jclass IntClass = (*env)->NewIntArray(env,Inum);
jobjectArray result = (*env)->NewObjectArray(env,3,IntClass,NULL);

int *temp1 = (*env)->GetIntArrayElements(env,IArr1,0); //IArr1是jIntArray型的

int *temp2 = (*env)->GetIntArrayElements(env,IArr1,0); //IArr2是jIntArray型的

int *temp3 = (*env)->GetIntArrayElements(env,IArr1,0); //IArr3是jIntArray型的

jintArray result1 = (*env)->NewIntArray(env,Inum);

jintArray result2 = (*env)->NewIntArray(env,Inum);
jintArray result3 = (*env)->NewIntArray(env,Inum);

(*env)->SetIntArrayRegion(env,result1,0,Inum,temp1);
(*env)->SetIntArrayRegion(env,result2,0,Inum,temp
2);
(*env)->SetIntArrayRegion(env,result3,0,Inum,temp
3);

(*env)->SetObjectArrayElement(env,result,0,result1);
(*env)->SetObjectArrayElement(env,result,1,result2);
(*env)->SetObjectArrayElement(env,result,2,result3);

(*env)->ReleaseIntArrayElements(env,IArr1,temp1,0);
(*env)->ReleaseIntArrayElements(env,IArr2,temp2,0);
(*env)->ReleaseIntArrayElements(env,IArr3,temp3,0);

过程大致是将jIntArray 转换成int*,然后将int*带入方法中(省,没贴出来),然后再将int*->jIntArray,最后将jIntArray添加到jobjectArray result中。

大致的类型转换也就这样了,其他的大同小异。

最后我还是说一下那个javah的命令行吧。因为我的java工程是有包的,所以这样写:

javah -classpath "到工程src的路径(如:G:\dir1\dir2\dir3\src)"  package.XXX

结束。。。。。。




  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值