免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2564 | 回复: 0
打印 上一主题 下一主题

再谈java调用dll [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-07-18 13:01 |只看该作者 |倒序浏览
再谈java调用dll



第一篇文章中讨论了使用javah命令生成C语言头文件的问题。这次完整讨论下java调用dll的过程。为方便讨论,例子中dll只导出了一个计算两个参数和的方法。
-------------------------
注:
java调用dll一般来说都是要根据头文件再去实现一下dll(c++,fortran等),有的童鞋可能会问:我只有一个dll文件,我想调用里面的方法,能不能直接用?这个据偶的水平没法解决,可能有高手会~~
-------------------------
    第一步:生成编写dll文件所需的C语言头文件
首先建立dllTest工程,在src目录下建包com.lxw;
建立java文件DllTest.java:
  1. package com.lxw;

  2. import java.lang.System;

  3. public class DllTest {
  4. static{
  5. System.loadLibrary("DllTest");  //载入dll,不用后缀
  6. }
  7. public native static int getSum(int i,int j);//函数声明
  8. }
复制代码
cmd进入dos下,进入D:\workspace\dllTest\src\com\lxw目录;
使用命令javac DllTest.java,编译文件,在lxw目录下生成DllTest.class文件;
使用命令cd..两次进入src目录;
使用命令javah -jni com.lxw.DllTest即可在src目录下生成com_lxw_DllTest.h的头文件,内容如下:
  1. /* DO NOT EDIT THIS FILE - it is machine generated */
  2. #include <jni.h>
  3. /* Header for class com_lxw_DllTest */

  4. #ifndef _Included_com_lxw_DllTest
  5. #define _Included_com_lxw_DllTest
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. /*
  10. * Class:     com_lxw_DllTest
  11. * Method:    getSum
  12. * Signature: (II)I
  13. */
  14. JNIEXPORT jint JNICALL Java_com_lxw_DllTest_getSum
  15.   (JNIEnv *, jclass, jint, jint);

  16. #ifdef __cplusplus
  17. }
  18. #endif
  19. #endif
复制代码
注意生成的头文件导出的函数名字为Java_com_lxw_DllTest_getSum;
-------------------------
    第二步:编写dll文件
打开vc选择新建工程DllTest,类型选择dll,可以将export symbols参数选上,帮你生成一些基本文件;也可不选;
将com_lxw_DllTest.h文件拷贝到工程目录下,我这里为:D:\vs2010projects\DllTest\DllTest;
将jawt_md.h,jni.h,jni_md.h文件(jdk的include目录和include\win32目录)拷贝到vc目录:C:\Program Files\Microsoft Visual Studio 10.0\VC\include;
这时工程并不包含拷贝进去的头文件,所以在工程的Header Files下右键导入com_lxw_DllTest.h文件;导入后同级的头文件还有stdafx.h和targetver.h文件,自动生成的DllTest.h可以删掉;
在Source Files下有三个文件dllmain.cpp,DllTest.cpp,stdafx.cpp,其中dllmain是dll必须的,自动生成,stdafx也是系统自动生成的,不用管,dllmain的内容如下:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"

  1. BOOL APIENTRY DllMain( HMODULE hModule,
  2.                        DWORD  ul_reason_for_call,
  3.                        LPVOID lpReserved
  4. )
  5. {
  6. switch (ul_reason_for_call)
  7. {
  8. case DLL_PROCESS_ATTACH:
  9. case DLL_THREAD_ATTACH:
  10. case DLL_THREAD_DETACH:
  11. case DLL_PROCESS_DETACH:
  12. break;
  13. }
  14. return TRUE;
  15. }
复制代码
这个就是dll的入口函数,和main winmain类似,主要处理dll的四种状态,不详谈了,有兴趣可以自己去了解;
DllTest.cpp文件可能会自动生成一些内容,vs2010的会实现一个int,class以及一个函数,这里将他们全部删除,编辑内容如下:
// DllTest.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "com_lxw_DllTest.h"
JNIEXPORT jint JNICALL Java_com_lxw_DllTest_getSum
(JNIEnv *, jclass, jint a, jint b){
          return a+b;
}
注意包含头文件,导出函数的格式可以从com_lxw_DllTest.h拷贝,不过多了参数a,b;
OK,编译工程,会在debug或者release目录下生成DllTest.dll文件;
我们可以看一下此文件导出的内容:
在dll所在目录下使用命令dumpbin -exports DllTest.dll >1.txt,打开1.txt,其中里面有内容:
ordinal hint RVA      name

         
1    0 00001010 _Java_com_lxw_DllTest_getSum@16 = _Java_com_lxw_DllTest_getSum@16
我们可以看到这个dll导出了一个函数,名字为_Java_com_lxw_DllTest_getSum;但是我们在后面的java文件中调用的时候使用getSum名字就可以;
-------------------------
    第三步:java中调用DllTest.dll
首先必须将DllTest.dll文件拷贝到java可以识别的路径,这里我拷贝到jdk的bin目录;
在刚才的java工程中新建java文件:
  1. package com.lxw;
  2. public class DllMain {

  3. public static void main(String[] args) {
  4. System.out.println(DllTest.getSum(10, 11));
  5. }
  6. }
复制代码
注意:这里直接使用getSum函数即可;而这里的DllTest.java文件就起到类似C语言中的头文件的作用;
----------------
应该没什么遗忘的了~~~  这里写的很详细了~~~  希望可以帮到大家~~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP