前言
第一次写JNI碰到了很多奇葩的问题,所以写下这篇博客,让看的同志们省点时间
正题
step1 获得.h头文件
用java写一个sayHello方法:
public class SayHello {
public native void sayHello(String name);
}
编译命令,在src目录下,将.java编译为.class文件:
javac com/nerbit/jni/hello/SayHello.java
javah命令,在bin目录下,从.class文件导出.h文件:
javah -jni com.nerbit.jni.hello.SayHello
得到的com_nerbit_jni_hello_SayHello.h内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_nerbit_jni_hello_SayHello */
#ifndef _Included_com_nerbit_jni_hello_SayHello
#define _Included_com_nerbit_jni_hello_SayHello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_nerbit_jni_hello_SayHello
* Method: sayHello
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_nerbit_jni_hello_SayHello_sayHello
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
step2 根据.h文件编写C++本地代码
打开VS(我的是vs2013),新建》项目》Visual C++》Win32(必须是win32,其他选项得到的dll可能会运行出错的~~~)
》填写项目名称》确定》下一步》选择DLL选项》完成
这是VS可能已经为我们生成了一些.h和.cpp文件,第一次为了简单,我们将他们全部删除,然后对项目进行一些配置:
1. 右击项目》属性》(右上角)配置管理器》设置"平台"为X64(按需选择)
2. 右击项目》属性》配置属性》C/C++》预编译头》设为不适用预编译头
3. 右击项目》属性》配置属性》VC++目录》在包含目录项目中添加两个目录:JAVA_HOME\include和JAVA_HOME\include\win32(JAVA_HOME为jdk安装目录)
然后将之前生成的com_nerbit_jni_hello_SayHello.h拷到该项目中,再创建一个hello.cpp文件:
#include <iostream>
#include "com_nerbit_jni_hello_SayHello.h"
using namespace std;
JNIEXPORT void JNICALL Java_com_nerbit_jni_hello_SayHello_sayHello
(JNIEnv* env, jobject obj, jstring name)
{
const char* pname = env->GetStringUTFChars(name, NULL);
cout << "hello, " << pname << endl;
}
最后,Ctrl+F7编译,得到Win32Project1.dll,接下来的步骤有两种方式完成:
1. 将Win32Project1.dll所在目录添加到环境变量中
2. 将Win32Project1.dll拷贝到C:/windows或C:/windows/system32/等系统目录中
step3 java中调用Dll
在SayHello类中加入Dll导入代码:
package com.nerbit.jni.hello;
public class SayHello {
static{
System.loadLibrary("Win32Project1");
}
public native void sayHello(String name);
}
然后,写一个测试类,调用该native方法:
package com.nerbit.jni.hello;
public class Test {
public static void main(String[] args) {
new SayHello().sayHello("mrJ");
}
}
运行该Test类,会得到输出:
Hello, Mrj