`

JNI VC DLL

    博客分类:
  • JAVA
阅读更多
Java调用dll 源码



JNI是JDK的一部分,用于为Java提供一个本地代码的接口。通过使用JNI编写的程序能够确保你的代码能够完全的移植到所有的平台。JNI使得运行在JVM虚拟机上的Java代码能够操作使用其它语言编写的应用程序和库,比如C/C++以及汇编语言等。此外JNI提供的某些API还允许你把JVM嵌入到本地应用程序中。下图表达了JNI所扮演的角色。



本文将通过一个实例来阐述使用VC++6.0来实现JNI的完整过程。使用JNI来整合本地代码和Java代码的步骤是确定的,没有再创作的余地,所以读者可以通过本文的步骤来逐步认识到,其实Java也是"没有什么不可以"的。

一、JNI的实现任务描述:在Java中调用windows下的消息框函数,并且从Java中传递一个字符串作为MessageBox函数的显示文本参数,显示在消息框的中间。下面让我们一起进入这一奇妙的旅程。

Step 1:写一个Java类,在这个类中包含了需要调用的本地方法的描述。


//WinMsgBox.java
package edu.netcom.jni;
public class WinMsgBox
{
static{
System.loadLibrary("WinMsgDll");    // (1)
}
public native void showMsgBox(String str);  // (2)
}




(1)中WinMsgDll是动态链接文件的文件名,不用加扩展名,因为在不同的平台下动态链接文件扩展名是不同的,由JVM自动识别,比如在 Solaris下,会被转换为WinMsgDll.so;而Win32环境下会转换为WinMsgDll.dll。这个文件名必须和Step 4中生成的文件名一致。这个文件的存放位置也很重要,它只能被放在JVM属性值java.library.path中指定的文件夹中。这个属性值可以使用 System.getProperty("java.library.path");来查看。一般情况下,至少放在这几个位置是确定可靠的,windows安装目录下的system32下面,JDK安装目录下的bin下面,以及调用主类文件的当前目录。

(2)中指明了你必须用本地代码实现的方法。

Step 2:提示符下使用命令javac -d . WinMsgBox.java编译Step 1编写的java文件。

此时会在当前目录下建立一个edu\netcom\jni目录结构,并且一个WinMsgBox.class文件存在其中。

Step 3:提示符下使用命令javah -jni edu.netcom.jni.WinMsgBox,此时会在当前目录下产生一个edu_netcom_jni_WinMsgBox.h文件,注意这个文件名是由(包名+类名)组成,中间用(_)隔开。此文件内容如下:


/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>                       // (1)
/* Header for class edu_netcom_jni_WinMsgBox */

#ifndef _Included_edu_netcom_jni_WinMsgBox
#define _Included_edu_netcom_jni_WinMsgBox
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     edu_netcom_jni_WinMsgBox
* Method:    showMsgBox
* Signature: (Ljava/lang/String;)V       // (2)
*/
JNIEXPORT void JNICALL Java_edu_netcom_jni_WinMsgBox_showMsgBox
  (JNIEnv *, jobject, jstring);           // (3)

#ifdef __cplusplus
}
#endif
#endif


(1)包含的jni.h存在于JDK安装目录下的include下面。

(2)(Ljava/lang/String;)V这是函数的标记符,当从本地方法端访问Java端的方法时,会用到这个标记符。JNI中为每种数据类型也定义了标记符,标记符的规则请查看JNI标准文档。

(3)在WinMsgBox.java中本地方法void showMsgBox(String str);的定义,被映射为JNIEXPORT void JNICALL Java_edu_netcom_jni_WinMsgBox_showMsgBox(JNIEnv *, jobject, jstring); 其中函数名的映射规则是(Java_包名_类名_方法名),如果存在重载的方法,则在后面还会增加每个参数的标记符。每一个方法映射到本地C函数后都会增加两个参数:JNIEnv *和jobject,关于这两个参数的用法将在后面阐述。另外,所有Java中的数据类型都会按一定规则进行映射为本地数据类型,这些数据类型都是在 jni.h中定义的。下面分别按照基本数据类型,和对象类型列出。

表1 Java基本类型到本地类型的映射


表2 Java中的类到本地类型的映射


Step 4:使用VC来编写本地方法的实现函数,最后编译成.dll文件。过程如下:

1) 选择new->projects(选择Win32 Dynamic-Link Library,以Step 1中指定的库名WinMsgDll作为工程名)->OK->An ampty DLL project->Finish。

2) 选择Tools->Options->Directories(添加目录D:\J2SDK1.4.2_03\INCLUDE和D:\J2SDK1.4.2_03\INCLUDE\WIN32)。在这些目录中包含JNI所需的头文件。

3) 将Step 3生成的edu_netcom_jni_WinMsgBox.h拷贝到WinMsgDll工程文件夹中。然后FileView中添加这个头文件。

4) 添加源文件WinMsgDll.cpp,内容如下:


#include "windows.h"
#include "edu_netcom_jni_WinMsgBox.h"
/*
* Class:     edu_netcom_jni_WinMsgBox
* Method:    showMsgBox
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_edu_netcom_jni_WinMsgBox_showMsgBox
(JNIEnv * env, jobject obj, jstring str){
const char *msg;
msg = env->GetStringUTFChars(str,0);
MessageBox(NULL,msg,"Java invoke",MB_OK);
env->ReleaseStringUTFChars(str,msg);
}


5) 编译生成WinMsgBox.dll文件。并将这个.dll文件拷贝到Step 1中说明的目录中。

注意:

1) 我们知道dll文件有两种指明导出函数的方法,一种是在.def文件中定义,另一种是在定义函数时使用关键字 __declspec(dllexport)。而在JNI中函数定义中的关键字JNIEXPORT实际在jni_md.h中如下定义,#define JNIEXPORT __declspec(dllexport),可见JNI默认的导出函数使用第二种。使用第二种方式产生的导出函数名会根据编译器发生变化,在有的情况下会发生找不到导出函数的问题(我们在JSP中使用JNI时就发生了这种问题,百思不得其解,后来强行加入一个.def文件就解决了)。因此最好是使用第一种方法自己定义一个.def文件来指明导出函数,这种情况下会强制使用第一种方式产生导出函数。本例中可以加入一个WinMsgDll.def文件,内容如下:


LIBRARY      "WinMsgDll"
DESCRIPTION  'message Windows Dynamic Link Library'
EXPORTS
    ; Explicit exports can go here
Java_edu_netcom_jni_WinMsgBox_showMsgBox


2) 从本例中,我们可以看到WinMsgBox.java决定了edu_netcom_jni_WinMsgBox.h,而后者又决定了 WinMsgDll.dll,也就是说,这是一个"牵一发而动全身"的过程,如果你改动了WinMsgBox.java,就一定要把整个步骤都走一遍(这一点一定要切记,因为这也是我们跌得鼻青脸肿后才得出的警世良言)。

3) 生成的.dll文件一定要正确拷贝到Step 1说明的目录中,本例中是将生成的WinMsgDll.dll和Step 5中的测试文件放在同一个目录下的(这也是我们困惑了很久才解决的问题)。

Step 5:编写一个测试文件来测试对WinMsgDll.dll的调用。测试文件TestJNI.java内容如下:


//TestJNI.java
import edu.netcom.jni.WinMsgBox;
public class TestJNI
{
public static void main(String[] args)
{
     WinMsgBox box = new WinMsgBox();
box.showMsgBox("Wonderful!!");
}
}


编译,运行,windows下的对话框跃然屏幕中间。到此为此,整个JNI的实现过程就已经完成了。(T117)



http://ztc.iteye.com/blog/133976
分享到:
评论

相关推荐

    Java JNI调用DLL方法

    在JAVA中如何通过JNI调用VC动态库,以及在如何在VC中调试

    JAVA JNI调用DLL完整步骤

    这两天要弄个JAVA调用DLL,研究了一下有点绕, java部分要生成.h头文件,所以弄了个例子在这分享下 JAVA调用DLL完整步骤 步骤里包括java部分代码及vc写的DLL代码

    JNI_VC6_Opencv做的dll_图片转视频

    JNI_VC6_Opencv做的图片转视频dll,其中的def有输出函数名,可以修改;在VC6下可直接编译通过;直接在eclipse中配置好后可以直接调用生成的dll。 遇到这方面需求,可以寻求帮助:415926459

    JNI_Demo.rar_DEMO_JNI DEMO_jni c_jni dll_vc6 dll

    一个简单的JNI例子,VC6.0生成DLL,java调用

    JNI实现的DEMO Java调用VC编写的DLL,对应于Linux .SO

    JNI实现的DEMO Java调用VC6编写的DLL,对应于Linux .SO 包含C的项目和Java的Eclipse项目

    java使用dll jni编程详细实例源码(java+vc)

    绝世好资源。 java通过jni操作vc实现的dll,你掌握了么? 这个资源不但包含java代码,vc代码,而且还有个自己总结的note。 一般的demo仅仅hello下,这个例子体现了传参、函数签名、返回值等等。

    jni.rar,Java调用VC编译dll接口源代码

    Java调用VC编译dll接口源代码,对于数类型也有说明

    JNI 调用(包含复杂对象传参)

    实现了jni 中java向vc dll传递list参数/String参数 对象的接口。vc代码可用vc6.0运行编译,java调用接口在src\common\CameraUtil.java里面。测试了好久才实现的(涉及到项目机密,部分资源文件没有上传,内部方法是...

    myo-java-JNI-Library:为myo-java项目构建JNI DLL所需的C ++ C文件

    为myo-java项目构建JNI DLL所需的C ++ / C文件。 视窗 ** MSVCP100.dll是必需的,作为VC ++的一部分安装,不确定其他方法。 ** ####需要设置几个环境变量: JAVA_HOME-指向JDK的基本安装 MYO_HOME-指向Myo ZIP的...

    java jni 传递汉字参数,读写ini

    java jni 传递汉字参数,包括java传入dll 从dll传出到java 读写ini 包括全部 java 代码 工程文件 全部vc++6.0 Dll 代码 工程文件 找了好久资料才完成的,传上来省的大家再走弯路。

    java jni 传递汉字参数,包括 in out

    java jni 传递汉字参数,包括java传入dll 从dll传出到java 包括全部 java 代码 工程文件 全部vc++6.0 Dll 代码 工程文件 找了好久资料才完成的,传上来省的大家再走弯路。

    JNI调用示例

    一直没找到一个现成的JAVA调用动态库DLL的示例程序,...1.先在VC文件夹中编译testAdd工程,生成原始DLL库 2.再在VC文件夹中编译mp300Lib工程,生成可供JAVA调用的DLL库 3.运行ECLIPSE文件夹的程序,可以正确计算结果

    【cmake实战十】c++从动态库(dll)导出类

    博客中用到的demo,[【cmake实战十】c++从动态库(dll)导出类](https://blog.csdn.net/junxuezheng/article/details/126908851)

    JNI技术手册 c/c++调用java

    采用vc6++ IDE,采用JNI技术实现。 51 1、 编译时 51 2、 运行时 51 程序的关键在 53 VII. JNI 53 一、 定义 53 二、 设计目的 54 三、 书写步骤 54 1) 编写java程序:这里以HelloWorld为例。 54 2) 编译 55 3) 生成...

    使用Netbeans和Visual Studio调试JNI应用程序

    本文介绍了如何在Netbeans中创建Java Swing GUI应用程序并将其与JNI DLL进行接口。

    Java进阶:JNI使用技巧点滴

    文章来源:csdn 作者:normalnotebook  摘要 本文为在 32 位 Windows 平台上实现 Java 本地方法提供了实用的示例、步骤和...我们首先用VC封装出图像转换的DLL,然后用JAVA的本地化方法JNI调用用于图像转换的DLL,最

    HelloWorld.zip

    本程序建立一个简单的JAVA调用DLL的程序实例,可以实现在java环境下调用dll,dll用vc编写。

    分割tif文件的dll(可处理JPEG压缩等tif)

    java和C# 对JPEG压缩的tif文件处理不是很好,前段时间用VC写了个分割tif文件的dll文件,可以处理任何压缩方式的dll文件,java可以直接调用。 调用时,java必须放在com包下,java名FileSplit.java,jni方法名 public ...

    使用JNative对条码打印机进行打印(转别人)

    使用JNative对条码打印机进行打印 因项目需要,对Godex EZ2300条码机进行调用打印, 驱动为Ez2000.dll, 用JNI可以实现调用,但比较麻烦, 需 要用到VC6进行DLL封装

Global site tag (gtag.js) - Google Analytics