JNI(在Java中调用C函数)
JNI调用C函数的步骤
- 编写Java代码
- 编译Java代码
- 生成C语言头文件
- 编写C代码
- 生成C共享库
- 运行Java程序
编写Java代码
package com.jni;
public class HelloJNI {
//本地方法声明
native void printHello();
native void printString(String str);
//加载库
static { System.loadLibrary("hellojni"); }
public static void main(String[] args)
{
HelloJNI myJNI = new HelloJNI();
//调用本地方法(实际调用的是使用C语言编写的JNI本地函数)
myJNI.printHello();
myJNI.printString("Hello World from printString fun");
}
}
在Java类中,使用“native”关键字,声明本地方法,该方法与用C/C++编写的JNI本地函数相对应。
“native”关键字告知Java编译器,在Java代码中带有该关键字的方法只是声明,具体由C/C++等其他语言编写实现
在Java中加载本地运行库时通常使用“静态块”。如果本地库未被正常加载,在使用本地方法调用本地库的C函数时,就会发生错误
编译Java代码
javac <文件路径>
例如:
javac HelloJNI.java
生成C语言头文件
javah <包含以native关键字声明的方法的Java类名称>
例如:
javah HelloJNI
HelloJNI.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */
#ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloJNI
* Method: printHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloJNI_printHello
(JNIEnv *, jobject);
/*
* Class: HelloJNI
* Method: printString
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_HelloJNI_printString
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
编写C代码
c文件中对应的方法名为生成的C语言头文件中对应的函数原型
hellojni.c
#include "HelloJNI.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_HelloJNI_printHello(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
return;
}
JNIEXPORT void JNICALL Java_HelloJNI_printString(JNIEnv *env, jobject obj, jstring string)
{
//GetStringUTFChars()是JNI函数,用来将Java字符串转成C语言字符串
const char *str = (*env)->GetStringUTFChars(env,string,0);
printf("%s\n", str);
return;
}
生成C共享库
gcc -shared -o <库的路径> <c文件路径>
gcc -shared -o hellojni.dll hellojni.c
注意事项
In file included from hellojni.c:1:com_jni_HelloJNI.h:2:17: jni.h: No such file or directory
复制JDK目录以下的这三个文件至编译器的include文件夹下- jdk\include\jni.h
- jdk\include\win32\jawt_md.h
- jdk\include\win32\jni_md.h
Exception in thread “main” java.lang.UnsatisfiedLinkError: H:\hellojni.dll: Can’t load IA 32-bit .dll on a AMD 64-bit platform
编译的版本应该与系统版本一致,64位的应使用64位的编译
运行Java程序
java <类名>
java HelloJNI
运行结果
Hello World!
Hello World from printString fun