java如何调用dll

jni这个东西比较复杂 因为前几天自己刚好做过这个么东西 所以才推荐你用JNative的哦(我也是刚接触这个是个菜鸟).....
看楼主这么执着那我就写个小例子 大家不要见笑(- -!)
假设现在有个A.dll里面有个方法叫做int add(int a, int b)现在就是要用jni去调用它
这里附上A.dll里面的代码(自己瞎个的吧 能用就行)
C/C++ code
        
        
#include " stdafx.h " BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } extern " C " int _declspec(dllexport) add( int a , int b) { return a + b; }


接下来我们的思路自己写个B.dll然后在这个dll里面去调用A.dll里面的这个add方法,然后通过JAVA去调用自己的这个B.DLL....
第一步: 随便建个txt文件 呵呵 当然后缀改上.JAVA写上
Java code
       
       
public class DemoJni{ public native int getNumber( int a, int b); public static void main(String[] args) { } }


然后javac一下 没错的话 javah 生成了DemoJni.h(如下)
C/C++ code
       
       
/* DO NOT EDIT THIS FILE - it is machine generated */ #include < jni.h > /* Header for class DemoJni */ #ifndef _Included_DemoJni #define _Included_DemoJni #ifdef __cplusplus extern " C " { #endif /* * Class: DemoJni * Method: getNumber * Signature: (II)I */ JNIEXPORT jint JNICALL Java_DemoJni_getNumber (JNIEnv * , jobject, jint, jint); #ifdef __cplusplus } #endif #endif


用VC++6.0写B.DLL
新建DLL工程名字为B 在Header FILES->添加这个DemoJni.h
然后就写B.cpp
C/C++ code
       
       
// B.cpp : Defines the entry point for the DLL application. // #include " stdafx.h " #include " jni.h " #include " DemoJni.h " BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } JNIEXPORT jint JNICALL Java_DemoJni_getNumber (JNIEnv * env, jobject o, jint x, jint y) { typedef int ( * ADD)( int , int ); // 函数指针类型 HINSTANCE Hint = ::LoadLibrary( " A.dll " ); // 加载我们刚才生成的dll ADD add = (ADD)GetProcAddress(Hint, " add " ); // 取得dll导出的add方法 return add(x,y); FreeLibrary(Hint); }

对了在VC++6.0要引入java的一些包 因为我们上面引入了#include "jni.h"
具体做法 工具->选项->目录->新建两个路径 :比如C:\PROGRAM FILES\JAVA\JDK1.5.0_14\INCLUDE
和C:\PROGRAM FILES\JAVA\JDK1.5.0_14\INCLUDE\WIN32
搞定后就可以编译了 然后在debug文件下面就生成了我们要的B.DLL
 然后A.DLL和B.DLL以及.java文件放一起咯
下面就是调用 改写我们的.java文件如下
Java code
       
       
public class DemoJni{ public native int getNumber( int a, int b); public static void main(String[] args) { System.loadLibrary( " B " ); DemoJni p = new DemoJni(); System.out.println(p.getNumber( 1 , 100 )); } }


然后java 一下 然后输出
101
然后OK!

这个东西如果用JNative来做的话 实在是太简单了- -!附上JNative的代码
Java code
       
       
import org.xvolks.jnative.JNative; import org.xvolks.jnative.Type; import org.xvolks.jnative.exceptions.NativeException; public class test { static JNative myjnative = null ; public int getnumber( int a, int b) throws NativeException, IllegalAccessException { try { if (myjnative == null ) { myjnative = new JNative( " A.dll " , " add " ); myjnative.setRetVal(Type.INT); } int i = 0 ; myjnative.setParameter(i ++ , a); myjnative.setParameter(i ++ , b); myjnative.invoke(); return myjnative.getRetValAsInt(); } finally { if (myjnative != null ) { myjnative.dispose(); } } } public static void main(String[] args) throws NativeException, IllegalAccessException { test uc = new test(); int result = uc.getnumber( 1 , 100 ); System.err.println( " result: " + result); } }



Jnative我觉得有个很好的地方就是有POINTER 指针这个东西.....
睡觉.......

 

=============================================================================================

例二

-----------------------本前言来自网络--------------------------

JNI技术的出现主要是基于三个方面的应用需求:

1. 解决性能问题

2. 解决本机平台接口调用问题

3. 嵌入式开发应用
-------------------------前言结束--------------------------------

下面动手来实现使用Jni调用本地方法,本实例演示 Java 调用 Native 本地方法传递参数并且返回结果。具体内容如下:

第一步:编写Java端代码

定义一个Java类

----------------------------------------------

public class TestNativeDemo { 
  
    // 声明本地方法 
    public native String testJni(String arg); 
  
    static { 
        // 加载DLL文件 
        System.loadLibrary("TestNativeDemoCPP"); 
    } 
  
    public static void main(String args[]) { 
        TestNativeDemo ob = new TestNativeDemo(); 
        // 调用本地方法 
        String result = ob.testJni("Hello,Jni"); // call a native method 
        System.out.println("TestNativeDemo.testJni=" + result); 
    } 
}

----------------------------------------------

编译之后在生成TestNativeDemo.class的bin目录下执行javah TestNativeDemo命令生成头文件TestNativeDemo.h

----------------------------------------------

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h> 
/* Header for class TestNativeDemo */
  
  
#ifndef _Included_TestNativeDemo //避免重复包含头文件  
#define _Included_TestNativeDemo 
#ifdef __cplusplus //c++编译环境中才会定义__cplusplus  
extern "C" { //告诉编译器下面的函数是c语言函数(因为c++和c语言对函数的编译转换不一样,主要是c++中存在重载)   
  
#endif 
/* 
 * Class:     TestNativeDemo 
 * Method:    testJni 
 * Signature: (Ljava/lang/String;)Ljava/lang/String; 
 */
JNIEXPORT jstring JNICALL Java_TestNativeDemo_testJni 
  (JNIEnv *, jobject, jstring); 
  
#ifdef __cplusplus 
} 
#endif 
#endif

----------------------------------------------

第二步:生成DLL库

1. 打开VS2008,创建一个名称为TestNativeDemoCpp的C++ Win32项目。在向导的应用程序类型处选择DLL,点完成。设置Release+Win32编译配置。

2. 将签名生成的TestNativeDemo.h文件拷贝到TestNativeDemoCpp项目的根目录下,然后在VS中右键头文件文件夹添加现有项把这个头文件包含进来,接下来就是编辑TestNativeDemoCpp.cpp文件。

----------------------------------------------

 

// TestNativeDemoCpp.cpp : 定义 DLL 应用程序的导出函数。 
#include "stdafx.h" 
  
#include <jni.h> 
#include "TestNativeDemo.h" 
#include <stdio.h> 
  
  
JNIEXPORT jstring JNICALL Java_TestNativeDemo_testJni (JNIEnv *env,jobject obj,jstring pString){ 
  
    //从jstring中获取本地方法传递的字符串 
  
     const char *nativeString = env->GetStringUTFChars(pString, 0);   
  
     printf("%s", nativeString);   
  
     //DON'T FORGET THIS LINE!!!   
     env->ReleaseStringUTFChars(pString, nativeString);   
  
     return pString; 
}

----------------------------------------------

3. VS开发环境默认不会识别jni.h头文件,在JDK中找到jni.h,并添加jni.h所在目录到当前工作路径:右键项目,属性-通用属性-C/C++-常规项在右边的附加包含目录中把%JAVA_HOME%/include和%JAVA_HOME%/include/win32加进来。

4. 右键项目的资源文件加入资源-版本信息。编译项目,在项目的Release下面找到TestNativeDemoCpp.dll文件,也有可能在项目的上层目录的release下边,跟设置有关。

第三步:运行Java调用DLL程序

把第二步产生的TestNativeDemoCpp.dll文件拷贝到第一步产生TestNativeDemo.class的同一目录。

执行命令:java TestNativeDemo

输出:Hello,JniTestNativeDemo.testJni=Hello,Jni

-----------------------结束--------------------------

http://www.linuxso.com/c/16798.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值