Java JNI调用本地C/C++
本实例以一个简单的例子来讲解JNI的实际调用
Java代码:
public class HelloNative {
public static native void greeting();
public static native int print(int width, int precision, double x);
}
编译:
javac HelloNative.java
生成.class文件后,使用javah命令生成一个C的头文件。(javah是jdk/bin目录下的一个可执行文件,可能需要配置好path环境变量)
javah HelloNative
这条命令会产生一个头文件HelloNative.h,生成的C头文件内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloNative */
#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloNative
* Method: greeting
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloNative_greeting
(JNIEnv *, jclass);
/*
* Class: HelloNative
* Method: print
* Signature: (IID)I
*/
JNIEXPORT jint JNICALL Java_HelloNative_print
(JNIEnv *, jclass, jint, jint, jdouble);
#ifdef __cplusplus
}
#endif
#endif
- 在Visual Studio新建一个C/C++ dll项目,取名叫HelloNative,在Debug后面选择位数,如果JDK为32位选择x86,64位则选择x64
- 将头文件复制到VisualStudio工作目录下,然后点击解决方案管理器的头文件->添加->现有项,选择复制进来的头文件。
- 接下来添加JNI依赖文件到visual studio工作目录 选择
项目->XXXX属性->C/C++->常规->附加包含目录添加以下两个文件夹
jdk\include
jdk\include\win32
我的添加完以后是这样的
接下来将HelloNative.h里面自动生成的两个函数复制到HelloNative.cpp。改变参数列表中的内容,添加代码如下:
#include <iostream>
#include <stdio.h>
#include <jni.h>
#include "stdafx.h"
#include "hellonative.h"
JNIEXPORT void JNICALL Java_HelloNative_greeting(JNIEnv *env, jclass cls) {
std::cout << "Greeting From Java!" << std::endl;
}
JNIEXPORT jint JNICALL Java_HelloNative_print(JNIEnv *env, jclass cls, jint width, jint precision, jdouble x) {
char fmt[30];
jint ret;
sprintf_s(fmt, "%%%d.%df", width, precision);
ret = printf(fmt, x);
fflush(stdout);
return ret;
}
接下来点击生成->生成HelloNative,没有报错以后到工作目录下的Debug目录找到HelloNative.dll文件,将文件复制到Eclipse项目的根目录,修改Java代码如下
public class HelloNative {
static {
System.loadLibrary("HelloNative");
}
public static native void greeting();
public static native int print(int width, int precision, double x);
public static void main(String[] args) {
greeting();
int count = print(8,4,3.14);
count += print(8,4,count);
System.out.println();
for(int i = 0; i < count; i++) {
System.out.print("-");
}
System.out.println();
}
}
注意:上面代码中System.loadLibrary方法是非常重要的,为了确保虚拟机在第一次使用该类之前就会装载这个文件,需要使用静态初始化代码块
至此运行Java代码,JNI调用完成