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 命令
-
生成 class 文件
-
-
cmd cd 到com.transsion.test上级目录,设置环境临时变量方便找到class文件 set classpath=e:\e_desktop\JavaProject\Helloworld\src,然后执行 javah -jni com.transsion.test.HelloNative
-
切换目录,执行两个命令
-
成功生成 .h文件
-
/* 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 文件
-
将jni.h,jni_md.h,HelloNative.h,HelloNative文件放在一起,记得将头文件include <jni.h> 修改为 include "jni.h"
-
此时c代码调用完整了,可以进行gcc编译为dll文件
-
为了让java可以发现dll文件,要将dll文件放入java环境中:\source\jdk\bin
-
运行java代码成功
3 小结
总之目标是让 java 可以成功拿到做好了的dll文件
- HelloNative.java
- HelloNative.class
- javah生产HelloNative.h文件
- c实现.h文件生产HelloNative.c
- 找到所有c文件和.h文件放在一起编译出dll文件
- 将dll文件放在java环境下
- 运行java程序
4 遇到的坑
-
.c文件未正确实现.h文件中声明的方法
-
gcc版本和java版本对应不上