给你推荐一本教程,可以下载的
http://www-900.ibm.com/developerWorks/cn/education/java/j-jni/tutorial/j-jni-2-1.html
http://www-900.ibm.com/developerWorks/cn/education/java/j-jni/tutorial/j-jni-2-1.html
解决方案 »
- [在线等] Android 地图开发,如何动态的向百度地图添加线移动的动态效果啊。
- 烽火、东软和亚信联创选哪个好?
- 如何去掉 MyEclipse启动后出现的“MyEclipse Start Page”页面
- 求助阿 org.hibernate.hql.ast.QuerySyntaxException: Unable to locate class [Test]
- hibernate加载配置问题
- 各位老大,这是什么错误啊,小弟先谢了!!
- 求助:jboss的启动出错了
- 电商商品数量有限的购买问题
- 有熟悉appfuse中的用户登录及权限验证机制的吗?
- 如何调applet呢?
- 急问,如何用weblogic的datasource连数据库?
- 初学EJB,就遇到一个问题,请各位多多指教!!高分!!!!
JNI是一种包容极广的编程接口,允许我们从Java应用程序里调用固有方法。它是在Java 1.1里新增的,维持着与Java 1.0的相应特性——“固有方法接口”(NMI)——某种程度的兼容。NMI设计上一些特点使其未获所有虚拟机的支持。考虑到这个原因,Java语言将来的版本可能不再提供对NMI的支持,这儿也不准备讨论它。
目前,JNI只能与用C或C++写成的固有方法打交道。利用JNI,我们的固有方法可以:
■创建、检查及更新Java对象(包括数组和字串)
■调用Java方法
■俘获和丢弃“异常”
■装载类并获取类信息
■进行运行期类型检查
所以,原来在Java中能对类及对象做的几乎所有事情在固有方法中同样可以做到。A.1.1 调用固有方法
我们先从一个简单的例子开始:一个Java程序调用固有方法,后者再调用Win32的API函数MessageBox(),显示出一个图形化的文本框。这个例子稍后也会与J/Direct一志使用。若您的平台不是Win32,只需将包含了下述内容的C头:
#include <windows.h>
替换成:
#include <stdio.h>
并将对MessageBox()的调用换成调用printf()即可。
第一步是写出对固有方法及它的自变量进行声明的Java代码:
class ShowMsgBox {
public static void main(String [] args) {
ShowMsgBox app = new ShowMsgBox();
app.ShowMessage("Generated with JNI");
}
private native void ShowMessage(String msg);
static {
System.loadLibrary("MsgImpl");
}
}在固有方法声明的后面,跟随有一个static代码块,它会调用System.loadLibrary()(可在任何时候调用它,但这样做更恰当)System.loadLibrary()将一个DLL载入内存,并建立同它的链接。DLL必须位于您的系统路径,或者在包含了Java类文件的目录中。根据具体的平台,JVM会自动添加适当的文件扩展名。
现在编译您的Java源文件,并对编译出来的.class文件运行javah。javah是在1.0版里提供的,但由于我们要使用Java 1.1 JNI,所以必须指定-jni参数:
javah -jni ShowMsgBox
javah会读入类文件,并为每个固有方法声明在C或C++头文件里生成一个函数原型。下面是输出结果——ShowMsgBox.h源文件(为符合本书的要求,稍微进行了一下修改):/* DO NOT EDIT THIS FILE
- it is machine generated */
#include <jni.h>
/* Header for class ShowMsgBox */#ifndef _Included_ShowMsgBox
#define _Included_ShowMsgBox
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: ShowMsgBox
* Method: ShowMessage
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL
Java_ShowMsgBox_ShowMessage
(JNIEnv *, jobject, jstring);#ifdef __cplusplus
}
#endif
#endif2. 名称管理和函数签名
JNI统一了固有方法的命名规则;这一点是非常重要的,因为它属于虚拟机将Java调用与固有方法链接起来的机制的一部分。从根本上说,所有固有方法都要以一个“Java”起头,后面跟随Java方法的名字;下划线字符则作为分隔符使用。若Java固有方法“过载”(即命名重复),那么也把函数签名追加到名字后面。在原型前面的注释里,大家可看到固有的签名。欲了解命名规则和固有方法签名更详细的情况,请参考相应的JNI文档。3. 实现自己的DLL
此时,我们要做的全部事情就是写一个C或C++源文件,在其中包含由javah生成的头文件;并实现固有方法;然后编译它,生成一个动态链接库。这一部分的工作是与平台有关的,所以我假定读者已经知道如何创建一个DLL。通过调用一个Win32 API,下面的代码实现了固有方法。随后,它会编译和链接到一个名为MsgImpl.dll的文件里:#include <windows.h>
#include "ShowMsgBox.h"BOOL APIENTRY DllMain(HANDLE hModule,
DWORD dwReason, void** lpReserved) {
return TRUE;
}JNIEXPORT void JNICALL
Java_ShowMsgBox_ShowMessage(JNIEnv * jEnv,
jobject this, jstring jMsg) {
const char * msg;
msg = (*jEnv)->GetStringUTFChars(jEnv, jMsg,0);
MessageBox(HWND_DESKTOP, msg,
"Thinking in Java: JNI",
MB_OK | MB_ICONEXCLAMATION);
(*jEnv)->ReleaseStringUTFChars(jEnv, jMsg,msg);
}
为实现JNI固有方法,最简单的方法就是在一个Java类里编写固有方法的原型,编译那个类,再通过javah运行.class文件。但假若我们已有一个大型的、早已存在的代码库,而且想从Java里调用它们,此时又该如何是好呢?不可将DLL中的所有函数更名,使其符合JNI命名规则,这种方案是不可行的。最好的方法是在原来的代码库“外面”写一个封装DLL。Java代码会调用新DLL里的函数,后者再调用原始的DLL函数。这个方法并非仅仅是一种解决方案;大多数情况下,我们甚至必须这样做,因为必须面向对象引用调用JNI函数,否则无法使用它们。
见<<Java编程思想>> 附录A 使用非JAVA代码