JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能。
解决JAVA对本地操作的一种方法就是JNI。
JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式)。通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各接口方法。
简单介绍及应用如下:
一、JAVA中所需要做的工作
在JAVA程序中,首先需要在类中声明所调用的库名称,如下:
static {
System.loadLibrary(“goodluck”);
}
在这里,库的扩展名字可以不用写出来,究竟是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("goodluck");
}
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++中所需要做的工作
用vc++创建一个Win32 Dynamic-Link Library工程,名字要与刚才java loadLibrary中相同,如goodluck
把刚用javah生成的testdll.h文件引入到项目中,同时把jdk搜索jni.h,jni_md.h两个文件放到\VC98\Include目录下面
接下来写一个实现testdll.h头文件的testdll.cpp文件,写好Build完后在Debug下生成goodluck.dll文件,
android的话,可以放到system/lib目录下面
对于已生成的.h头文件,C/C++所需要做的,就是把它的各个方法具体的实现。然后编译连接成库文件即可。再把库文件拷贝到JAVA程序的路径下面,就可以用JAVA调用C/C++所实现的功能了。
接上例子。我们先看一下testdll.h文件的内容:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* 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中需要调用的一致,这里就是goodluck.dll
把goodluck.dll拷贝到testdll.class的目录下,java testdll运行它,就可以观察到结果了。
分享到:
相关推荐
JNI使得Java应用程序可以直接调用C/C++的函数,或者让C/C++代码调用Java方法。 1. **JNI基础**:JNI的核心是定义了一套C/C++的头文件和接口,这些接口提供了与Java虚拟机(JVM)通信的方法。开发者需要编写C++代码...
总的来说,Java调用C++生成的DLL涉及到JNI规范、C++编程、Windows动态库知识以及Java本地方法调用等多方面内容。通过以上步骤,我们可以在Java程序中充分利用C++的性能优势,实现跨语言的高效协作。如果你遇到具体...
4. **生成JNI头文件**:在Java项目中,使用`javah`工具生成JNI头文件,这个文件包含了Java本地方法的C/C++声明。例如: ``` javah -jni DLLTest ``` 这将生成`DLLTest.h`文件。 5. **实现JNI接口**:在C++源...
不过这些语言的调用机制和C/C++略有不同,例如在Java中需要使用JNI(Java Native Interface)来调用本地方法,在C#中则使用P/Invoke,而Matlab则使用其自身的DLL调用方法。在调用过程中,需要注意数据类型和内存管理...
接下来,使用`javah`命令生成JNI头文件`NativeHello.h`,该文件包含了本地方法的C/C++声明,以便于我们在C++代码中实现这些方法。 ``` javah NativeHello ``` 此时,你的项目目录中应该包含`NativeHello.java`、`...
本教程将详述如何使用C++编写DLL动态链接库,并通过Java的Java Native Access (JNA)库进行调用,从而实现Java程序对C++功能的调用。 首先,我们需要了解DLL是什么。DLL(Dynamic Link Library)是Windows操作系统中...
在实现过程中,我们先要在C++的DLL中编写获取CPU ID的函数,然后在Java端使用JNI定义对应的native方法,并通过`System.loadLibrary`加载DLL。当Java调用这个native方法时,实际会执行DLL中的相应函数,从而获取CPU ...
- **生成头文件**:使用`javah`工具(在Java SDK中)生成C++头文件,该文件包含了JNI函数原型和Java方法签名的映射。 - **编写C++代码**:根据生成的头文件编写C++源码,实现本地方法的具体逻辑,并使用JNI函数...
在C++编程中,动态链接库(DLL)是一种常见的代码复用方式,它允许程序在运行时加载和使用库中的函数或类。本篇将基于【cmake实战十】的主题,详细阐述如何从C++动态库(DLL)导出类,并结合实际的`test10`示例进行...
最后,运行Java程序(`Java HelloJni`),如果一切配置正确,Java程序将加载DLL,并执行C++的本地方法,打印出“Hello Dynamic Link Library has been calling!”和“Java_HelloJni_displayHelloJni method has been...
Java调用DLL(Dynamic Link Library)是跨平台编程中的一项技术,主要应用于Java与C++或者其他支持DLL的原生代码之间交互。在Java中,通过JNI(Java Native Interface)技术可以实现对DLL的调用,从而利用C++库提供...
将生成的`MakeDLL.dll`文件复制到包含调用DLL的Java文件的相同目录下。 2. **Java代码** 修改Java类`Main`,加载DLL并调用native方法。 ```java public class Main { static { System.loadLibrary("MakeDLL...
本文将详细阐述使用JNI调用C++生成的DLL文件的步骤。 首先,你需要编写一个简单的Java类,该类声明了一个native方法。在示例中,创建了一个名为`HelloJni`的类,包含一个名为`displayHelloJni`的native方法。这个...
接下来,我们需要在NDK环境中创建C/C++源文件,例如`src/main/cpp/jni/test.c`,并实现与Java中声明的本地方法相对应的函数。在这个文件中,我们将定义`JNIEXPORT`开头的函数,这些函数将被Java层调用。例如,对于`...
8. **VC++与Java的交互**: 在Java中,使用`System.loadLibrary()`加载DLL,然后通过JNI的`FindClass`, `GetMethodID`, `GetStaticMethodID`等方法找到对应的Java方法,最后调用`CallIntMethod`, `CallVoidMethod`等...
JNI是Java平台的一部分,它允许Java代码和其他语言写的代码进行交互,这里可能是为了在Java程序中调用我们的C++ DLL。 至于`jni_md.h`,它是JNI的平台特定头文件,包含了针对不同操作系统平台的JNI函数声明。 总结...
3. **本地方法实现(Native Method Implementation)**: 使用C++或C编写本地方法的具体实现,这部分代码通常放在`.c`或`.cpp`文件中。 4. **动态链接库(Dynamic Link Library)**: 编译本地方法后,会生成一个动态...
使用JNI,开发者需要编写C或C++的本地方法来实现DLL,并在Java中通过`System.loadLibrary()`加载。这个过程包括: - 创建一个`.h`头文件,定义JNI函数签名。 - 编写`.c`或`.cpp`源文件,实现这些函数并链接到DLL。...
1. **Java调用C/C++程序**:Java Native Interface (JNI)技术允许Java程序直接调用C/C++代码。 2. **C/C++调用MATLAB**:通过MATLAB提供的C API,C/C++程序可以调用MATLAB引擎。 #### 实现步骤 ##### 步骤一:编写...
JNI是一种规范,允许Java代码调用本地方法,即非Java代码,如C或C++编写的方法。以下是使用JNI调用DLL的基本步骤: 1. **创建Java接口**:定义一个Java接口,该接口声明了要调用的本地方法。这些方法的签名应与DLL...