Java本地方法(native)

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. 生成头文件

  • 执行javah -jni test
  • 生成头文件如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class test */

#ifndef _Included_test
#define _Included_test
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     test
 * Method:    print
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_test_print
  (JNIEnv *, jclass, jstring);

#ifdef __cplusplus
}
#endif
#endif

3. C/C++实现

  • dllmain.c名字任取
#include "jni.h"
#include <stdio.h>
#include "test.h"


JNIEXPORT void JNICALL Java_test_print(JNIEnv * env, jclass cls, jstring str) {
	// jstring不能直接使用
	char * JAVAchars = (char*)(*env) -> GetStringUTFChars(env, str, NULL);
    printf("%s", JAVAchars);
}

4. 生成动态连接库

  • .dll文件
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 {

	// dll本地缓存目录
    public static final String DLL_CACHE = System.getProperty("java.io.tmpdir");
	// dll文件名
    public static final String DLL_NAME = "dllmain.dll";

    static {
    	// dll缓存到本地
        cacheDll();
        // 从本地加载dll文件
        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();
                }
            }
        }
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值