JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能。解决JAVA对本地操作的一种方法就是JNI。
JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式)。通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各接口方法。
简单介绍及应用如下:
一、JAVA中所需要做的工作
在JAVA程序中,首先需要在类中声明所调用的库名称,如下:
static {
System.loadLibrary(“testdll”);
}
在这里,库的扩展名字可以不用写出来,究竟是DLL还是SO,由系统自己判断。
还需要对将要调用的方法做本地声明,关键字为native。并且只需要声明,而不需要具体实现。如下:
public native static void set(int i);
public native static int get();
然后编译该JAVA程序文件,生成CLASS,再用JAVAH命令,JNI就会生成C/C++的头文件。
例如程序testdll.java,内容为:
public class testdll
{
static
{
System.loadLibrary("testdll");
}
public native static int get();
public native static void set(int i);
public static void main(String[] args)
{
testdll test = new testdll();
test.set(10);
System.out.println(test.get());
}
}
用javac testdll.java编译它,会生成testdll.class。
再用javah testdll,则会在当前目录下生成testdll.h文件,这个文件需要被C/C++程序调用来生成所需的库文件。
二、C/C++中所需要做的工作
对于已生成的.h头文件,C/C++所需要做的,就是把它的各个方法具体的实现。然后编译连接成库文件即可。再把库文件拷贝到JAVA程序的路径下面,就可以用JAVA调用C/C++所实现的功能了。
接上例子。我们先看一下testdll.h文件的内容:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class testdll */
#ifndef _Included_testdll
#define _Included_testdll
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: testdll
* Method: get
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_testdll_get
(JNIEnv *, jclass);
/*
* Class: testdll
* Method: set
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_testdll_set
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
在具体实现的时候,我们只关心两个函数原型
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass);
和
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);
这里JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的。而jint是以JNI为中介使JAVA的int类型与本地的int沟通的一种类型,我们可以视而不见,就当做int使用。函数的名称是JAVA_再加上java程序的package路径再加函数名组成的。参数中,我们也只需要关心在JAVA程序中存在的参数,至于JNIEnv*和jclass我们一般没有必要去碰它。
好,下面我们用testdll.cpp文件具体实现这两个函数:
#include "testdll.h"
int i = 0;
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass)
{
return i;
}
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j)
{
i = j;
}
编译连接成库文件,本例是在WINDOWS下做的,生成的是DLL文件。并且名称要与JAVA中需要调用的一致,这里就是testdll.dll
对于在VC6.0中,可以打开VC++6.0,新建->; 工程 ->; win32 Dynamic-Link Library .在向导中选择空工程。
把刚才javah生成的那个头文件加入工程 .然后 文件->;新建->;textFile 自己做一个
.cpp文件.实现自己的native函数.
对于在visual stdio 2005中,可以新建一个WIN32的空项目,下一步中选择DLL和空项目。然后把上面的testdll.h和testdll.cpp加进去,编译就可以生成testdll.dll文件
通常情况下,VC的编译器会找不到jni.h和jni_md.h头文件,这两个头文件可以在JDK目录下的include下找到。vc6.0也有可能找不到cl.exe这个编译器,可以上网下载后再设置环境变量就可以了。通常这个编译器会在VC目录下的vc/bin目录下可以找到的。
把testdll.dll拷贝到testdll.class的目录下,java testdll运行它,就可以观察到结果了
分享到:
相关推荐
JAVA通过JNI调用C++代码函数的示例DEMO
利用JNI技术实现Java中调用C++编写的函数库示例程序源码,并附上参考JNI文档。 详情见本人博客:Java学习之通过JNI调用C/C++编写的dll链接库(图文教程)(http://write.blog.csdn.net/postlist)
详细内容请看https://blog.csdn.net/qq_34950682/article/details/95790190
Android调用C++函数的DEMO.结合博客中的文章来看会更好
Android Studio项目,此Demo实现Java调用C++函数,然后C++函数回调Java方法、纯C++直接调用Java方法,此为github地址链接
android jni 调用本地函数 c++ 格式 完整代码
V. Eclipse+CDT+MinGW 进行JAVA调用C/C++ 34 一、 安装eclipse3.2。 34 二、 安装MinGW。 34 1、 下载MinGW 34 2、 安装 34 3、 安装版本 34 4、 选择安装的编译器 34 5、 选择安装路径,下一步 35 6、 等待下载...
cocos2d-x 通过JNI实现c/c++和Android的java层函数互调, 本文主要实现两个功能: (1)通过Android... 首先来简单学习一下JNI的相关知识,我这篇文章中简单实现了怎么在Android Java层调用c++函数。要想使用JNI,必须得…
C++使用JNI多线程回调java代码例子,因为依赖了我的一些库和头文件,没有传上去,编译不过,但是大家可以参考一下,如何使用C++多线程调用java函数
在这个例子中,我们使用...注意,我们在实现函数中使用了`JNIEnv *env`和`jobject obj`这两个参数,它们分别表示JNI的环境指针和当前对象的引用。这些参数可以让我们方便地在Java和C++之间传递数据和调用其他本地方法。
1. 在应用的JAVA代码中调用NDK中C/C++实现的函数。 2. 在NDK开发中的C/C++代码调用应用中JAVA类的静态函数。 3. 在NDK开发中的C/C++代码调用应用中JAVA类当前传入NDK中的实例的函数。 4. 在NDK开发中的C/C++代码调用...
这个静态方法可以从 Java 代码中直接调用,而不需要使用 JNI 接口函数。 这是 C++ 语言编写的 JNI 接口函数,用于在 Java 层调用本地方法。这个接口函数的作用是创建新线程,并在新线程中调用 callJavaStaticMethod...
C++调用Android函数工程Demo详情见博客
Java代码中调用C/C++代码,当然是使用JNI,JNI是Java native interface的简写,可以译作Java原生接口,下面看实例吧
做NDK项目,不仅会用到java层通过jni调用C++层函数的情况,也会有需要C++可以调用java层函数的需求,简单整理了C++反调java函数的流程。
NDK开发时,C/C++调用Java的函数的一些案例; 传递int类型参数: https://blog.csdn.net/niuba123456/article/details/80978500 传递String类型参数: https://blog.csdn.net/niuba123456/article/details/80978916 ...
用JAVA 的JNI调用本地c/C++的函数模块,以库函数的形式提供给Java 程序使用
Chap12:基本JNI调用技术(c/c++与java互调) 93 Chap13:JNI的c代码中,另外一个线程获取 JNIEnv. 96 chap 14:当JNI遇到多线程--java对象如何被C++中的多个线程访问?. 97 chap 15:JNI在多线程中的应用... 101 ...
JNI编程之C++回调Java函数的详细调用方法
学习JNI编译时,缺少的jni.h和jni_md.h头文件,Java调用C和C++函数时的JNI使用区别: 注意:jni.h头文件中对于***.c & ***.cpp采用不同的定义