VC++ 6.0 JNI的实现
来源:互联网 发布:淘宝上的祛痘产品知乎 编辑:程序博客网 时间:2024/05/15 23:45
说明
本人从事Android开发工作,目前在研究JNI相关知识,关于JNI的学习,个人认为应该先从JNI本身入手,然后逐步扩展到Android方向,而不是直接开始Android方向JNI的开发和学习。为什么使用VC++ 6.0 ,因为大多数人大学学习C/C++的时候使用过这个工具,小巧,高效,虽然目前使用它开发时不现实的,但是用来学习还是很不错的。
JNI编写流程
编写带有native声明的方法的java类
使用javac命令编译所编写的java类
然后使用javah + java类名生成扩展名为h的头文件
使用C/C++实现本地方法
将C/C++编写的文件生成动态连接库
运行java工程并调用JNI
编写带有native声明的方法的java类
使用之前需要注意的是,一定要用32位的JDK,为什么?因为我们要利用vc++6.0生成dll库文件,但是vc++6.0是不支持生成64位dll的,所以JDK需要使用32位,不明白没关系,我们待会详细说。
HelloJni.java
public class HelloJni{ static{ System.loadLibrary("HelloJni"); } public native static void hello(String s); public native static String say(); public static void main(String[] args){ HelloJni hello = new HelloJni(); hello.hello("Hello JNI !"); System.out.println(hello.say()); } }
使用javac命令编译所编写的java类
进入java文件目录,生成class文件。
javac HelloJni.java
然后使用javah + java类名生成扩展名为h的头文件
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: hello * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_HelloJni_hello (JNIEnv *, jclass, jstring); /* * Class: HelloJni * Method: say * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_HelloJni_say (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif
该文件里面包含了需要实现的本地方法申明。
对于已生成的.h 头文件, C/C++所需要做的,就是把它的各个方法具体的实
现。然后编译连接成库文件,如果是在Linux环境下面就是Android里面常见的so库,而Windows下面则是dll文件。
在具体实现的时候,我们只关心两个函数原型
NIEXPORT void JNICALL Java_HelloJni_hello(JNIEnv *, jclass, jstring); NIEXPORT void JNICALL Java_HelloJni_hello(JNIEnv *, jclass, jstring);
这里 JNIEXPORT 和 JNICALL 都是 JNI 的关键字,表示此函数是要被 JNI 调用的。而
jstring
是JNI中定义的一种数据类型,目的是使得java的String类型和本地代表字符序列(c/c++中的字符数组)能够相互转化,我们可以把它当作一种中间类型,jstring
暂且可以当做String
来看待。可以看到函数的名称是 Java_再加上 java 类的 package路径再加函数名组成的。JNIEnv*和 jclass 我们暂时可以忽略。
使用C/C++实现本地方法
知道我们要实现的本地方法之后,我们可以用c++来实现这两个方法,并编译链接成dll文件。
我们新建一个HelloJni.cpp
文件,将要实现的方法拷贝进去,并将HelloJni.c
包含进去。
#include "HelloJni.h" const char* s; JNIEXPORT void JNICALL Java_HelloJni_hello(JNIEnv * env, jclass cls, jstring str) { s = env->GetStringUTFChars(str, 0); } JNIEXPORT jstring JNICALL Java_HelloJni_say(JNIEnv * env, jclass cls) { return env->NewStringUTF(s); }
将C/C++编写的文件生成动态连接库
实现好本地方法之后,接下来就是编译并链接成dll文件了。
打开vc6.0,我们新建一个Win32 Dynamic-Link Library
工程,并勾选一个简单的DLL工程
。
我们可以看到该工程里面已经有一个HelloJni.cpp
文件了.
#include "stdafx.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call,LPVOID lpReserved) { return TRUE; }
注意#include "stdafx.h"
待会会用到,接下来,这时候我们将之前生成的HelloJni.c
和创建的HelloJni.cpp
复制并覆盖到工程目录下,将#include "stdafx.h"
添加到我们实现的HelloJni.cpp
里面去,那么工程就变成这样。
#include "stdafx.h" #include "HelloJni.h" const char* s; JNIEXPORT void JNICALL Java_HelloJni_hello(JNIEnv * env, jclass cls, jstring str) { s = env->GetStringUTFChars(str, 0); } JNIEXPORT jstring JNICALL Java_HelloJni_say(JNIEnv * env, jclass cls) { return env->NewStringUTF(s); }
点击Build
之后编译没有问题进入到HelloJni工程目录下面的Debug
目录下面就可以找到HelloJni.dll
文件。那么dll文件就生成好了。
如果点击
Compile
之后报错,没有关系,先点击上面的Build
之后再点Compile
就会发现没有错误了。
运行java工程并调用JNI
拿到dll文件之后,将dll拷贝到HelloJni.class目录下面,运行java程序。
java HelloJni
输出
Hello JNI !
如果你是用的64位JDK的话,那么就会报错。
Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\johnny.wu\Desktop\HelloJni.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform
所以这里需要32位的JDK,如果必须用64位的JDK那么就只能使用比VC6.0更强大的编译器生成64位的dll文件。
- VC++ 6.0 JNI的实现
- VC++ 6.0 实现 JNI (jni 入门)
- 例解用 VC++ 6.0 实现 JNI
- 例解 VC++ 6.0 实现 JNI
- 解用 VC++ 6.0 实现 JNI
- 用 VC++ 6.0 实现 JNI
- 解用 VC++ 6.0 实现 JNI
- 利用VC++6.0实现JNI的最简单的例子.
- 利用VC++6.0实现JNI的最简单的例子
- 利用VC++6.0实现JNI的最简单的例子.
- VC++6.0实现JNI的最简单的例子
- 例解 VC++ 6.0 实现 JNI(ZT)
- 例解 VC 实现 JNI
- 利用VC++6_0实现JNI的最简单的例子【转载】
- Java用JNI实现对用VC++编写的动态库的调用
- 简单的JNI实现
- JNI的实现流程
- JNI的实现原理
- 深入理解递归以及汉诺塔问题[数据结构]
- Notepad++配合MinGW直接编译运行C/C++代码的窍门
- tomcat native 安装
- JDK自动拆箱下,三目运算符的潜规则
- 运行时的用法积累
- VC++ 6.0 JNI的实现
- 01. redis 简介&&安装
- android 自定义控件之一
- 怎样使用OpenCV进行人脸识别
- pycharm快捷键、常用设置、包管理
- cell与Model的那些事
- The Java™ Tutorials — Generics :Unbounded Wildcards 非受限通配符
- 矩阵交换行
- 自定义控件篇 第二章 输入事件(触摸滑动,Scroller,事件分发机制)