现在的位置: 首页 > 综合 > 正文

window下利用JNI在java代码中调用c/c++接口

2013年01月05日 ⁄ 综合 ⁄ 共 2327字 ⁄ 字号 评论关闭
这里在window XP环境下用一个helloWorld,示例该如何使用jni。 一些细节请参考《android框架揭秘》这本书,写的非常详细。

一些术语:
本地代码:指用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文件里的函数原型拷贝过来,然后再修改,可以减少错误。
#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)根据自己的位置修改。

5.通过jni调用jni本地函数

java HelloJNI

结果如下:

我们在下一篇将介绍在本地代码调用java对象以及对对象字段、方法的一些操作。

抱歉!评论已关闭.