在前面我们完成了最简单的HelloWorld——Java通过JNI调用C语言编写的.dll文件。下面我们继续来讨论如何在Java和C之间传递参数。
下面是java native方法不带参数public native String getName();
的情况下javah工具生成的.h头文件:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: getName
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_HelloWorld_getName
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
当我们把native方法改成public native String getName(String str);
后我们发现javah工具生成的.h头文件定义的函数参数变成了:
JNIEXPORT jstring JNICALL Java_HelloWorld_getName
(JNIEnv *, jobject, jstring);
多了一个jstring变量用以传递来自Java的String变量。jstring类型是String在JVM的存储方式,它不同于C语言中常用的String(通常用char* 来存储),我们要用相应的JNI函数对就string进行转换。
简单地我们可以这样做:
JNIEXPORT void JNICALLJava_MyJavaClass_printName(JNIEnv *env, jobject obj,
jstring name)
{
const char *str= (*env)->GetStringUTFChars(env,name,0);
printf(“%s”, str);
//need to release this string when done with it in
//order to avoid memory leak
(*env)->ReleaseStringUTFChars(env, name, str);
}
这里的函数使用都是非常简单的,不多做解释。更多的函数说明参考:
http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#string_operations
类型映射
JNI为Java中的一些变量类型定义了相对应的C类型,主要有两大类:
基本类型
Java Type | Native Type | Size in bits |
---|---|---|
boolean | jboolean | 8, unsigned |
byte | Jbyte | 8 |
char | Jchar | 16, unsigned |
short | Jshort | 16 |
int | Jint | 32 |
long | Jlong | 64 |
float | Jfloat | 32 |
double | Jdouble | 64 |
void | Void | n/a |
引用类型
相关阅读
http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#string_operations