这里在window XP环境下用一个helloWorld,示例该如何使用jni。 一些细节请参考《android框架揭秘》这本书,写的非常详细。
一些术语:
本地代码:指用c/c++编写的原生代码。
本地方法:指用java编写的类的方法。
本地函数:区分于本地方法,指用c/c++编写函数。
一些术语:
本地代码:指用c/c++编写的原生代码。
本地方法:指用java编写的类的方法。
本地函数:区分于本地方法,指用c/c++编写函数。
1.在java类中声明本地方法
文件HelloJNI.java中的内容:
class HelloJNI
{
native void printHello(); // 本地方法
native void printString(String str); // 本地方法
static { System.loadLibrary("hellojni"); } // java中的静态块用于加载c/c++编写的动态库 (window下是hellojni.dll,linux下是hellojni.so)
public static void main(String args[])
{
HelloJNI myJNI = new HelloJNI();
// 调用本地方法(实际调用了c语言编写的本地函数)
myJNI.printHello(); // 调用本地方法,对应的框架层会通过jni调用c/c++编写的对应接口
myJNI.printString("hello, this is a jni call!");
}
}
2.使用javah命令生成包含JNI本地函数原型的头文件.
命令:
javac HelloJNI.java
javah HelloJNI
生成 HelloJNI.h头文件,包含了c/c++本地代码的原型函数说明。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */
#ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloJNI
* Method: printHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloJNI_printHello
(JNIEnv *, jobject);
/*
* Class: HelloJNI
* Method: printString
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_HelloJNI_printString
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
说明:
函数名称由这几部分构成:类名_本地方法名_返回值类型(共同参数)。
1.其中JNIEnv是jni接口的指针,jni本身提供许多函数用于创建java对象或调用对应方法。
2.jobject是java本地数据类型,java提供的一套与java数据类型相对应的本地类型,是的本地语言可以使用java的数据类型。不必担心不同平台(win、linux)的类型与对应的字节数不一样。因此从java中接收数据,使用java本地数据类型即可.
java类型 | java本地类型 | 占用内存大小 |
byte | jbyte | 1 |
short | jshort | 2 |
int | jint | 4 |
long | jlong | 8 |
float
|
jfloat
|
4
|
double
|
jdouble
|
8
|
char
|
jchar
|
2
|
boolean
|
jboolean
|
1
|
类 | Jclass | |
对象 | Jobject | |
String | Jstring |
最下面三种是引用类型,还有其他几种,可参考http://java.sun.com/docs/books/jni
3.实现JNI本地函数
HelloJNI.c文件内容, 编写这个代码时,首先把上面生成的.h文件里的函数原型拷贝过来,然后再修改,可以减少错误。
HelloJNI.c文件内容, 编写这个代码时,首先把上面生成的.h文件里的函数原型拷贝过来,然后再修改,可以减少错误。
#include "HelloJNI.h"
#include <stdio.h>
/*
* Class: HelloJNI
* Method: printHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloJNI_printHello
(JNIEnv *env, jobject obj)
{
printf("hello, world!\n");
return;
}
/*
* Class: HelloJNI
* Method: printString
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_HelloJNI_printString
(JNIEnv *env, jobject obj, jstring string)
{
const char *str = (*env)->GetStringUTFChars(env, string, 0);
printf("%s!\n", str);
return;
}
4.生成c共享库
cl -I"C:\Program Files\Java\jdk1.7.0\include" -I"C:\Program Files\Java\jdk1.7.0\include\win32" -LD hellojni.c -Fehellojni.dll
注意:需要安装VC++2008 Express Editions或者VS2008,在自带的Visual studio 2008 Command Prompt中输入。
上述的jdk目录(C:\Program Files\Java\jdk1.7.0)根据自己的位置修改。