本文记录一个基础的JNI例子及过程中遇到的问题解决。
1、定义一个JAVA类如下:
package jnidemo01; public class JniHello { public native void displayHelloWorld(); static { System.loadLibrary("HelloDll"); } public static void main(String[] args) { new JniHello().displayHelloWorld(); } }
2、编译成.class文件后,采用javah jnidemo.JniHello生成一个.h头文件;
3、在vs里创建一个类型为dll的空win32项目,拷贝进刚才的.h文件,并实现其.cpp,如下:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class jnidemo01_JniHello */ #ifndef _Included_jnidemo01_JniHello #define _Included_jnidemo01_JniHello #ifdef __cplusplus extern "C" { #endif /* * Class: jnidemo01_JniHello * Method: displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_jnidemo01_JniHello_displayHelloWorld (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
#include <jni.h> #include "JniHello.h" #include <stdio.h> JNIEXPORT void JNICALL Java_jnidemo01_JniHello_displayHelloWorld(JNIEnv *env, jobject obj) { printf("Hello world!/n"); return; }
4、编译生成dll文件并放置在java工程下,执行java程序,控制台打印"Hello world!"
在此过程中主要遇到的问题如下:
1、找不到jni.h
在工程 -> 右键 -> c/c++ -> 包含附件目录中 增加:
jdk的include目录 和 includewin32目录,主要是包含入jni.h和jni_md.h等;
2、error LNK1123: 转换到 COFF 期间失败
项目”-->“属性” --> “清单工具”,然后选择"输入和输出’ --> ‘嵌入清单’,将后面的‘是’改成‘否’;
3、no ** in java.library.path
1、将dll放置在工程目录下
2、采用System.load + 绝对路径
4、Can't load IA 32-bit .dll on a AMD 64-bit platform
vs2010默认的配置属性是win32,通过解决方案 -> 右键 -> 配置属性 ,修改win32为x64
备注:如果是调用第三方DLL的话,相当于写一个JNI的DLL然后在这个DLL中调用第三方;
//*****************************************************************************
1、在Android Studio中采用Jni调用原生库类似,只是需要引入NDK,可以认为是一个Android平台下的交叉编译环境。
2、建JAVA类、生成.H文件、到实现.H中的接口,于纯JNI类似;
3、在Android Studio中不再需要Android.mk 都编译脚本,由Gradle支持,如下:
defaultConfig {
applicationId "com.base.fredric.ndk01"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
ndk {
moduleName = "NdkTest"
ldLibs "log", "z", "m"
abiFilters "armeabi", "armeabi-v7a", "x86"
}