前言
本文承接 之前的
<a href="http://www.reibang.com/p/476aae319808">jni簡單數(shù)據(jù)</a>,采用String和數(shù)組的的類型傳遞和返回參數(shù),以深入對(duì)于jni的了解
String 類型
修改 JniHello.java
/**
* Created by act64 on 2017/5/25.
*/
public class JniHello {
static{
System.loadLibrary("nativehello");
}
public static void main(String[]arg){
JniHello jniHello =new JniHello();
System.out.println( jniHello.hello("world"));
}
public native String hello(String str);
}
為了方便搞明白數(shù)據(jù)類型和參數(shù)以及對(duì)于的描述符,還是偷懶用javah生成
//在terminal里面輸入
javac JniHello.java
javah JniHello
這樣目錄下就生成了JniHello.h文件
打開 JniHello.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JniHello */
#ifndef _Included_JniHello
#define _Included_JniHello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JniHello
* Method: hello
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_JniHello_hello
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
我們?cè)谝獾氖荢ignature 和JNICALL Java_JniHello_hello的參數(shù)和返回值,將這些參數(shù)運(yùn)用到我們上一篇簡書寫的hello.c中
#include <stdio.h>
#include <jni.h>
jstring c_hello(JNIEnv * env, jobject mJobject,jstring val){
const jbyte *str;
str = (*env)->GetStringUTFChars(env, val, NULL);
if (str == NULL) {
return NULL; /* OutOfMemoryError already thrown */
}
printf("java IN %s", str);
(*env)->ReleaseStringUTFChars(env, val, str);
return (*env)->NewStringUTF(env, "helloJNIStr");
}
const JNINativeMethod methods[]={
{"hello","(Ljava/lang/String;)Ljava/lang/String;",(jstring *)c_hello},
};
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved)
{
JNIEnv *env;
jclass cls;
if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) {
return JNI_ERR; /* JNI version not supported */
}
cls = (*env)->FindClass(env, "JniHello");
if (cls == NULL) {
return JNI_ERR;
}
if((*env)->RegisterNatives(env,cls,methods,1)<0){
return JNI_ERR;
}
return JNI_VERSION_1_4;
}
然后編譯文件 蓝厌,命令在上一篇簡書中有詳細(xì)介紹捂人,可以去翻一下 <a href="http://www.reibang.com/p/476aae319808">jni簡單數(shù)據(jù)</a>
gcc -fPIC -I /usr/lib/jvm/java-1.7.0-openjdk-amd64/include -shared -o libnativehello.so hello.c
export LD_LIBRARY_PATH=./
javac JniHello.java
java JniHello
結(jié)果如下
String輸出.png
數(shù)組
String就是這樣傳的晋被,數(shù)組也是類似的,改寫java文件和c文件
/**
* Created by act64 on 2017/5/25.
*/
public class JniHello {
static{
System.loadLibrary("nativehello");
}
public static void main(String[]arg){
JniHello jniHello =new JniHello();
int [] a={1,2,3};
int []b=jniHello.hello(a);
for (int i=0;i<3 ;i++ ) {
System.out.println( b[i]);
}
}
public native int[] hello(int[] ints);
}
hello.c
#include <stdio.h>
#include <jni.h>
#include <stdlib.h>
jintArray c_hello(JNIEnv * env, jobject mJobject,jintArray arr){
jint *carr;
jint i, sum = 0;
//將jintarray轉(zhuǎn)為c++的int數(shù)組指針
carr = (*env)->GetIntArrayElements(env, arr, NULL);
if (carr == NULL) {
return 0; /* exception occurred */
}
//獲得數(shù)組長度
jint length=(*env)->GetArrayLength(env,arr);
jint *buff;
//動(dòng)態(tài)生成數(shù)組
//需要頭文件stdlib
//并且malloc使用完后應(yīng)該free
buff=malloc(length*sizeof(jint));
if (buff==NULL)
{
//使用完后,應(yīng)該釋放內(nèi)存陨囊,下同
(*env)->ReleaseIntArrayElements(env, arr, carr, 0);
return 0;
/* code */
}
for (i=0; i<length; i++) {
sum += carr[i];
buff[i]=sum*sum;
}
//創(chuàng)建新的intarray
//用于返回給java
jintArray reArray=(*env)->NewIntArray(env,length);
//將c++數(shù)組的內(nèi)容爷怀,拷貝到要返回給java的intarray去
(*env)->SetIntArrayRegion(env,reArray,0,length,buff);
(*env)->ReleaseIntArrayElements(env, arr, carr, 0);
printf("sum = %d\n", sum);
free(buff);
return reArray;
}
//描述符和返回類型
//利用javah命令可以看到
const JNINativeMethod methods[]={
{"hello","([I)[I",(jintArray *)c_hello},
};
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved)
{
JNIEnv *env;
jclass cls;
if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) {
return JNI_ERR; /* JNI version not supported */
}
cls = (*env)->FindClass(env, "JniHello");
if (cls == NULL) {
return JNI_ERR;
}
if((*env)->RegisterNatives(env,cls,methods,1)<0){
return JNI_ERR;
}
return JNI_VERSION_1_4;
}
然后運(yùn)行編譯命令≡确看輸出
gcc -fPIC -I /usr/lib/jvm/java-1.7.0-openjdk-amd64/include -shared -o libnativehello.so hello.c
javac JniHello.java
java JniHello
輸出如下
圖片.png
結(jié)語
本文主要講了 jni中較為復(fù)雜的數(shù)據(jù)類型洒忧,字符串和數(shù)組的傳遞,下一篇將要講一講類對(duì)象的傳遞