怎样用 jni来交互java与 cc++
发布时间:2025-05-22 10:58:12 发布人:远客网络
一、怎样用 jni来交互java与 c/c++
JNI是Java Native Interface的缩写,中文为JAVA本地调用。使用JNI可以很方便的用我们的Java程序调用C/C++程序。很多时候,某些功能用Java无法实现,比如说涉及到底层驱动的一些功能,这时候我们就可以利用JNI来调用C或者C++程序来实现,这就是JNI的强大之处。但是JNI也有它的缺点,使用java与本地已编译的代码交互,通常会丧失平台可移植性。
下面是一个JNI例子,调用C++输出"hello world":
第一步:创建Java类,在里面定义一个本地方法(用native关键字修饰的方法)
public native void sayHello();
第二步:使用javah命令(javah类的全路径)生成本地方法的C++头文件
在DOS窗口中进入工程所在目录,然后执行javah com.test.TestNative命令,执行完之后就会在当前目录生成一个后缀名为.h的头文件,如com_test_TestNative.h,这个头文件是根据包名和类名来命名的。
1/* DO NOT EDIT THIS FILE- it is machine generated*/
3/* Header for class com_test_TestNative*/
5#ifndef _Included_com_test_TestNative
6#define _Included_com_test_TestNative
11* Class: com_test_TestNative
15 JNIEXPORT void JNICALL Java_com_test_TestNative_sayHello
15、16行是对TestNative类中的本地方法sayHello()的声明。这个h文件相当于我们在java里面的接口,这里声明了一个 Java_com_test_TestNative_sayHello(JNIEnv*, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致。
第三步:编写C/C++本地代码,生成动态链接库文件
首先在VC6.0(当然也可以用其他工具)中创建一个dll工程---Win32 Dynamic-Link Library工程。然后将上面生成的头文件com_test_TestNative.h添加到该工程中,然后创建一个源文件引用该头文件并且实现头文件中本地函数的功能:
2#include"com_test_TestNative.h"
4 JNIEXPORT void JNICALL Java_com_test_TestNative_sayHello(JNIEnv*env, jobject obj)
6 cout<<"hello world!"<<endl;
这里因为com_test_TestNative.h中引入了jni.h所以要将jni.h加入到VC6.0安装目录下的Include目录中。jni.h在JDK安装目录下的include中,同时得件include/win32中的两个头文件jawt_md.h、jni_md.h也导入到VC6.0中。
将所依赖的头文件导入之后,我们就可以构建该工程了,按F7就行了,完了会在工程目录中的Degug目录下生成一个动态链接库文件,我这里生成的是NativeCode.dll。我们就可以将该dll文件拷贝到环境变量path所包含的目录下给咱们的Java程序调用了,为了方便,我们也可以将dll所在的工程目录加入到环境变量path中去,这样可以避免每次都要拷贝的麻烦。注意修改环境变量之后要重启myeclipse。
4 public native void sayHello();
9 public static void main(String[] args){
10 System.loadLibrary("NativeCode");
11 TestNative tNative= new TestNative();
第10行是加载动态链接库,JVM只需要加载一次就可以调用了,“NativeCode”是上面生成的动态链接库的名字,不含后缀名。
运行该程序,成功打印输出了"hello world"。
二、Java 运行时JNI问题
1、在执行java的时候,要输入完整的包名+类名。否则在以后的测试调用过程中会发生java.lang.UnsatisfiedLinkError这个异常。
Java是一种可以撰写跨平台应用程序的面向对象的程序设计语言。Java技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。
三、jni调用java和c是同个线程吗
1、在JNI(Java Native Interface)调用中,Java代码和C/C++代码通常是在同一个应用程序进程中执行的,这意味着它们运行在同一台虚拟机(JVM)中。因此,如果你在Java代码中调用C/C++本地方法,这两个代码片段通常会在同一个线程中执行。
2、要验证这一点,你可以在Java和C/C++代码中分别获取当前线程的ID,并对比两者是否相同。
3、在Java中,你可以使用以下代码获取当前线程的ID:
4、long javaThreadId= Thread.currentThread().getId();
5、在C或C++中,你可以使用POSIX线程函数`pthread_self`来获取当前线程的ID:
6、long cThreadId=(long)pthread_self();
7、或者,如果你使用的是Windows API,你可以使用`GetCurrentThreadId`函数:
8、DWORD cThreadId= GetCurrentThreadId();
9、请注意,尽管Java和C/C++代码通常在同一线程中执行,但这并不意味着它们始终如此。多线程环境下,线程调度和执行的细节由JVM和操作系统的线程模型共同决定。此外,如果使用了某些特定的JNI库或框架,它们可能会在底层管理额外的线程或线程池。因此,具体的线程行为可能会根据你的应用程序设计和JNI调用方式而有所不同。