上图简单的介绍了JNI的概念、应用场景、原理、使用步骤,下面通过JNI实现一个Hello world实例。
1. 在Java类中声明native方法,NativeTest.java。
package com.ghsau;
public class NativeTest {
public native void sayHello();// native修饰的方法不能有方法体
public static void main(String[] args) {
System.loadLibrary("native");// 加载DLL
NativeTest nt = new NativeTest();
nt.sayHello();
}
}
2. 用javah将编译后的class文件生成头文件,我用的是eclipse,自动编译的class文件在bin目录下,在dos环境下进入到bin目录,执行javah com.ghsau.NativeTest,这样就在class文件所在目录下生成了com_ghsau_NativeTest.h头文件。
3. 用vc++新建一个Win32 Dynamic Link Library工程(我的是vc++6.0),输入工程名(我的是native),然后选择create a simple dll project,创建成功之后,在source files下有native.cpp(和工程名一样)和StdAfx.cpp,在Header Files下有StdAfx.h,首先先编译一下StdAfx.cpp,会在工程所在目录debug文件夹下生成native.pch文件,这个文件在编译native.cpp的时候需要用到;然后在Header
Files中引入com_ghsau_NativeTest.h、jni.h(com_ghsau_NativeTest.h需要,在jdk安装目录include下)、jni_md.h(jni.h需要,在include/win32下);最后编辑com_ghsau_NativeTest.h、native.cpp,编辑后代码如下:
com_ghsau_NativeTest.h
/* 将<jni.h>修改为"jni.h" */
#include "jni.h"
/* Header for class com_ghsau_NativeTest */
#ifndef _Included_com_ghsau_NativeTest
#define _Included_com_ghsau_NativeTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_ghsau_NativeTest
* Method: sayHello
* Signature: ()V
* 生成dll需要在方法前加上extern "C" __declspec(dllexport)
*/
extern "C" __declspec(dllexport)
JNIEXPORT void JNICALL Java_com_ghsau_NativeTest_sayHello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
native.cpp
#include "stdafx.h"
#include "com_ghsau_NativeTest.h"
#include <iostream.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
JNIEXPORT void JNICALL Java_com_ghsau_NativeTest_sayHello(JNIEnv * env, jobject obj)
{
cout<<"Hello World!"<<endl;
}
编辑完毕,编译native.cpp文件,编译无问题之后build,就会在debug文件夹下生成dll动态链接库了。
4. 配置环境变量,将dll所在目录放到环境变量PATH中。
5. 重启eclipse,eclipse是在启动时读取环境变量,然后运行NativeTest,java,打印出Hello world。
以上就是实现JNI的一套过程,JNI的优势和劣势很明显,优势图中已经说明。我想最大的劣势就是失去跨平台性。
分享到:
相关推荐
5.2.1 第一板斧--初识影子对象 5.2.2 第二板斧--由弱生强 5.2.3 第三板斧--破解生死魔咒 5.2.4 轻量级的引用计数控制类LightRefBase 5.2.5 题外话-三板斧的来历 5.3 Thread类及常用同步类分析 5.3.1 一个变量引发的...
第2章通过Android源码中的一处实例深入地介绍了JNI技术。 第3章围绕init进程,介绍了如何解析init.rc以启动Zygote和属性服务(property service)的工作原理。 第4章剖析了zygote和system_server进程的工作...
5.2.1 第一板斧——初识影子对象 / 96 5.2.2 第二板斧——由弱生强 / 103 5.2.3 第三板斧——破解生死魔咒 / 106 5.2.4 轻量级的引用计数控制类LightRefBase / 108 5.2.5 题外话-三板斧的来历 / 109 5.3 Thread类及...
4.1 初识ViewRoot和DecorView 174 4.2 理解MeasureSpec 177 4.2.1 MeasureSpec 177 4.2.2 MeasureSpec和LayoutParams的对应关系 178 4.3 View的工作流程 183 4.3.1 measure过程 183 4.3.2 layout过程 193 ...
3.1.2 初识binder /102 3.2 binder驱动的原理和实现 /102 3.2.1 binder驱动的原理 /102 3.2.2 binder驱动的实现 /103 3.3 binder的构架与实现 /132 3.3.1 binder的系统构架 /132 3.3.2 binder的机制和原理 /133 3.4 ...
/ 144 3.5 View的滑动冲突 / 154 3.5.1 常见的滑动冲突场景 / 155 3.5.2 滑动冲突的处理规则 / 156 3.5.3 滑动冲突的解决方式 / 157 第4章 View的工作原理 / 174 4.1 初识View Root和Decor View / 174 4.2 ...
4.1 初识ViewRoot和DecorView / 174 4.2 理解MeasureSpec / 177 4.2.1 MeasureSpec / 177 4.2.2 MeasureSpec和LayoutParams的对应关系 / 178 4.3 View的工作流程 / 183 4.3.1 measure过程 / 183 4.3.2...
3.1.2 初识binder /102 3.2 binder驱动的原理和实现 /102 3.2.1 binder驱动的原理 /102 3.2.2 binder驱动的实现 /103 3.3 binder的构架与实现 /132 3.3.1 binder的系统构架 /132 3.3.2 binder的机制和原理 /...
第1篇 初识Android系统 第1章 准备知识 1.1 Linux内核参考书籍 1.2 Android应用程序参考书籍 1.3 下载、编译和运行Android源代码 1.3.1 下载Android源代码 1.3.2 编译Android源代码 1.3.3 运行Android...
第1篇 初识Android系统 第1章 准备知识 1.1 Linux内核参考书籍 1.2 Android应用程序参考书籍 1.3 下载、编译和运行Android源代码 1.3.1 下载Android源代码 1.3.2 编译Android源代码 1.3.3 运行Android模拟器 ...
第1篇初识Android系统 第1章 准备知识................................................................ 2 1.1 Linux内核参考书籍.................................................. 2 1.2 Android应用程序...