JNI——Java调用DLL
来源:互联网 发布:java联机游戏代码实现 编辑:程序博客网 时间:2024/06/07 23:30
基本概念
JNI其实是Java Native Interface的简称,也就是java本地接口。它提供了若干的API实现了和Java和其他语言的通信(主要是C&C++)。对于那些对性能要求比较高的Java程序或者Java无法处理的任务无疑是一个很好的方式。
实验方案
假设我们的Java程序为J2C.java,C程序为J2C.c,Java与C之间的通信函数名为write2proc; write2proc的声明位于J2C.java,实现位于J2C.c;
具体操作
编写并编译Java程序
javac J2C.java => J2C.class
生成C/C++头文件
javah J2C => J2C.h (安装JDK后,
JAVAHOME应该已加入 PATH, 否则使用绝对路径,例如/usr/bin/javah)编写对应的C/C++程序:J2C.c
生成C/C++目标文件
gcc -I/usr/lib/jvm/java-6-openjdk-amd64/include -I/usr/lib/jvm/java-6-openjdk-amd64/include/linux -fPIC -c J2C.c => J2C.o//windows 环境下实现cl -I %JAVA_HOME%/include -c J2C.c
具体CL操作及环境配置:点击链接
- 生成C/C++共享库
gcc -shared -Wl,-soname,libj2c.so.1 -o libj2c.so.1.0 J2C.o => libj2c.so.1.0//重命名cp libj2c.so.1.0 libj2c.so => libj2c.so//windows 下实现cl /LD J2C
- 将共享库加入动态链接库的路径(此例为当前目录)
建议将生成的dll/so 文件放在项目的根目录
共享库加入动态链接库的具体方法
- 执行Java程序,实现跨语言通信
java J2C
具体实现代码
J2C.java
import java.lang.management.ManagementFactory;import java.lang.management.RuntimeMXBean; public class J2C{ static { try{ // 此处即为本地方法所在链接库名 System.loadLibrary("j2c"); } catch(UnsatisfiedLinkError e) { System.err.println( "Cannot load J2C library:\n " + e.toString() ); } } //声明的本地方法 public static native int write2proc(int pid); public static void main(String[] args){ //获取本进程(即主线程)的pid final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean(); final String info = runtime.getName(); final int index = info.indexOf("@"); if (index != -1) { final int pid = Integer.parseInt(info.substring(0, index)); System.out.println(info); System.out.println(pid); write2proc(pid); } try{ Thread.sleep(8000); } catch(InterruptedException e){ e.printStackTrace(); } }}
Java程序中System.loadLibrary参数名表示要载入的C/C++共享库,第6步生成的共享库名必须与该参数一致,即System.loadLibrary(Name) 对应共享库名libName.so (共享库名必须以lib开头)||Windows中共享库名为Name.dll
生成的J2C.h
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class J2C */ #ifndef _Included_J2C#define _Included_J2C#ifdef __cplusplusextern "C" {#endif/* * Class: J2C * Method: write2proc * Signature: (I)I */JNIEXPORT jint JNICALL Java_J2C_write2proc (JNIEnv *, jclass, jint); #ifdef __cplusplus}#endif#endif
头文件自动生成,不要修改它;
按照注释的说明是在J2C.java文件的类J2C的方法write2proc处定义,故C程序的实现函数必须与该处签名一致
C程序J2C.c
#include <stdio.h> #include "J2C.h" JNIEXPORT long JNICALL Java_J2C_write2proc(JNIEnv * env, jobject arg, jint pid) { printf("current pid is %d\n", pid); return 0; }
因为C程序里#include “J2C.h”而J2C.h又#include <jni.h>, 而gcc里面默认环境并不知道jni.h是什么东西,故编译时需要告诉编译器jni.h的位置(jni.h在jdk的JAVA_HOME/include下面),所以才有了上面的编译参数
总结
Java中方法的原型声明与C/C++对应的实现文件定义必须一致(可以通过自动生成的C/C++头文件来比较),尤其是类名和方法名;
Java中System.loadLibrary()载入的共享库名必须与后面C/C++生成的共享库名一致。
常见错误
JNI java.lang.UnsatisfiedLinkError
详情:点击链接
Can’t load IA 32-bit .dll on a AMD 64-bit platform
详情:点击链接
类型错误
注意int通过javah 自动生成的.h文件中是Jint,是long型。
- JNI——Java调用DLL
- java 调用dll JNI
- Java使用JNI调用dll
- java调用dll方法--JNI
- JNI--Java中调用DLL
- java 通过jni调用dll
- Java调用C/C++实现的DLL动态库——JNI
- Java调用C/C++实现的DLL动态库——JNI
- JNA—JNI终结者,java调用dll、ocx、so最简单的方法
- JNA—JNI终结者,java调用dll、ocx、so最简单的方法
- JNA—JNI终结者,java调用dll、ocx、so最简单的方法
- Java通过JNI调用本地DLL
- JNI-Java(Eclipse)调用dll/so
- JAVA通过JNI调用DLL问题
- JNI技术实现JAVA程序调用dll
- 浅谈JNI的使用--java调用dll
- java调用dll(JNI的使用)
- jni java调用win32 dll的方法
- CodeForces 498C Array and Operations(最大流)
- 小练习:用socket实现Linux和Windows之间的通信
- 8月3日所学
- 高级ios工程师和初级工程师的区别
- 博客开篇
- JNI——Java调用DLL
- SpringMVC 文件上传配置,多文件上传,使用的MultipartFile
- JS之原型与原型链
- Android利用Binder类实现对服务的调用
- hough拟合圆弧
- 犀牛——第7章数组 7.1 创建数组
- securityoverridehacking challenge 解题思路汇总——Advanced
- 关闭Android 应用的三种方法
- BootStrap输入框组