Java本地方法(native)
1. 编写native方法
public class test {
static {
System . loadLibrary ( "dllmain" ) ;
}
public static void main ( String [ ] args) {
print ( "你好" ) ;
}
public native static void print ( String s) ;
}
2. 生成头文件
# include <jni.h>
# ifndef _Included_test
# define _Included_test
# ifdef __cplusplus
extern "C" {
# endif
JNIEXPORT void JNICALL Java_test_print
( JNIEnv * , jclass, jstring) ;
# ifdef __cplusplus
}
# endif
# endif
3. C/C++实现
# include "jni.h"
# include <stdio.h>
# include "test.h"
JNIEXPORT void JNICALL Java_test_print ( JNIEnv * env, jclass cls, jstring str) {
char * JAVAchars = ( char * ) ( * env) -> GetStringUTFChars ( env, str, NULL ) ;
printf ( "%s" , JAVAchars) ;
}
4. 生成动态连接库
gcc -I"D:\Software\ApplicationSoftware\JDK\include" -I"D:\Software\ApplicationSoftware\JDK\include\win32" -Wl,--add-stdcall-alias -shared -o dllmain.dll dllmain.c
gcc -m64 -Wl,--add-stdcall-alias -I"D:\Software\ApplicationSoftware\JDK\include" -I"D:\Software\ApplicationSoftware\JDK\include/win32" -shared -o dllmain.dll dllmain.c
5. 运行
idea打包
javah -jni -classpath "C:\Users\admin\Desktop\untitled\src\main\java" org.example.impl.Print
打包jar包后,不能从jar包加载dll
文件 从classpath中copy到本地缓存中,从本地加载
public class WindowsPrinter implements Print {
public static final String DLL_CACHE = System . getProperty ( "java.io.tmpdir" ) ;
public static final String DLL_NAME = "dllmain.dll" ;
static {
cacheDll ( ) ;
System . load ( DLL_CACHE + File . separator + DLL_NAME) ;
}
@Override
public native void install ( ) ;
@Override
public native void uninstall ( ) ;
public static void cacheDll ( ) {
InputStream inputStream = null ;
FileOutputStream outputStream = null ;
try {
inputStream = Thread . currentThread ( ) . getContextClassLoader ( ) . getResourceAsStream ( DLL_NAME) ;
outputStream = new FileOutputStream ( DLL_CACHE + File . separator + DLL_NAME) ;
byte [ ] buffer = new byte [ 1024 ] ;
int len = 0 ;
while ( ( len = inputStream. read ( buffer) ) != - 1 ) {
outputStream. write ( buffer, 0 , len) ;
}
outputStream. flush ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
} finally {
if ( inputStream != null ) {
try {
inputStream. close ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
}
if ( outputStream != null ) {
try {
outputStream. close ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
}
}
}
}