9.25 完成一次hello-jni操作

83 阅读2分钟

9.25 完成一次hello-jni操作

实现一次原生的jni

目标是,让java可以找到c编译后生成的dll文件。

1 java代码和c代码撰写

(先写java代码,然后javac编译java代码生成.class文件,然后javah利用.class自动生成.h头文件,然后写c代码实现头文件中的方法)

  • com.transsion.test目录下新建 HelloNative.java 文件

	package com.transsion.test;

	public class HelloNative {
		static
	    {
	        System.loadLibrary("HelloNative");
	    }

	    public static native void sayHello();

	    @SuppressWarnings("static-access")
	    public static void main(String[] args)
	    {
	        new HelloNative().sayHello();
	    }
	}
  • cmd cd 到com.transsion.test目录下,执行 javac HelloNative.java

    • 执行 javac 命令

      javac-class.png

    • 生成 class 文件

      good-class.png

  • cmd cd 到com.transsion.test上级目录,设置环境临时变量方便找到class文件 set classpath=e:\e_desktop\JavaProject\Helloworld\src,然后执行 javah -jni com.transsion.test.HelloNative

    • 切换目录,执行两个命令

      setPath-javah.png

    • 成功生成 .h文件

      resultFile.png


	/* DO NOT EDIT THIS FILE - it is machine generated */
	#include <jni.h>
	/* Header for class com_transsion_test_HelloNative */

	#ifndef _Included_com_transsion_test_HelloNative
	#define _Included_com_transsion_test_HelloNative
	#ifdef __cplusplus
	extern "C" {
	#endif
	/*
	 * Class:     com_transsion_test_HelloNative
	 * Method:    sayHello
	 * Signature: ()V
	 */
	JNIEXPORT void JNICALL Java_com_transsion_test_HelloNative_sayHello
	  (JNIEnv *, jclass);

	#ifdef __cplusplus
	}
	#endif
	#endif

	#include "HelloNative.h"
	#include <stdio.h>

	JNIEXPORT void JNICALL Java_com_transsion_test_HelloNative_sayHello(JNIEnv * a, jclass b){
	    printf("Hello,JNI");
	}

2 java代码和c代码链接

(先将c文件补充完整,然后编译出dll文件,然后放在java可以找到的目录下)

  • 到jdk目录下找到jni.h 和 jni_md.h 文件

    find_jni.png

    find_jni_md.png

  • 将jni.h,jni_md.h,HelloNative.h,HelloNative文件放在一起,记得将头文件include <jni.h> 修改为 include "jni.h"

    together.png

  • 此时c代码调用完整了,可以进行gcc编译为dll文件

    gcc.png

    dll.png

  • 为了让java可以发现dll文件,要将dll文件放入java环境中:\source\jdk\bin

java-dll.png

  • 运行java代码成功

    java-result.png

3 小结

总之目标是让 java 可以成功拿到做好了的dll文件

  • HelloNative.java
  • HelloNative.class
  • javah生产HelloNative.h文件
  • c实现.h文件生产HelloNative.c
  • 找到所有c文件和.h文件放在一起编译出dll文件
  • 将dll文件放在java环境下
  • 运行java程序

4 遇到的坑

  • .c文件未正确实现.h文件中声明的方法

    wrong-declare.png

  • gcc版本和java版本对应不上