欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > linux中Java程序调用C程序中方法的实现方式浅析

linux中Java程序调用C程序中方法的实现方式浅析

2025/2/26 0:21:49 来源:https://blog.csdn.net/leijie0322/article/details/139860781  浏览:    关键词:linux中Java程序调用C程序中方法的实现方式浅析

在Linux中,Java程序可以通过JNI(Java Native Interface)来调用C程序的方法。

在这里插入图片描述在这里插入图片描述

Linux系统环境,Java调用C的主要流程如下:
1、创建Java类文件,如NativeLibrary.java
2、编写Java代码,加载.so共享库(C程序生成该名称的.so共享库),并声明本地方法
3、使用javac编译Java类,生成.class文件
4、使用javah对.class文件生成C头文件,该文件包含了Java和C之间通信所需的函数声明
5、创建C语言源文件,如NativeLibrary.c
6、编写C程序代码并实现要被Java调用的方法
7、使用gcc编译C程序和C头文件生成动态链接库(共享库.so文件)
8、运行Java程序,并调用C程序中的方法

1、Java类文件

创建NativeLibrary.java文件,内容如下:

public class NativeLibrary {static {System.loadLibrary("mylib"); // 加载名为"mylib"的共享库}public native void printHello(); // 声明本地方法public static void main(String[] args) {new Hello().printHello(); // 调用本地方法}
}

其中,System.loadLibrary(“mylib”);为加载共享库, public native void printHello();为声明本地方法。

在Java中,加载本地库(通常是C或C++编写的库,以.dll、.so或.dylib等形式存在)主要有两种方式:System.loadLibrary()和System.load()。这两种方法用于与Java Native Interface (JNI)交互,使Java程序能够调用本地代码。
使用 System.loadLibrary()允许Java运行时根据平台自动定位和加载本地库。你只需要提供库的名字(不包括扩展名,如.dll或.so),Java运行时会在标准位置搜索这些库。
使用 System.load()允许你直接指定本地库的完整路径。这在库不在标准位置或需要加载特定版本的库时非常有用。
当使用System.loadLibrary()时,通常需要在linux环境设置环境变量LD_LIBRARY_PATH,如export LD_LIBRARY_PATH=“.so文件所在路径”

2、C头文件

javah是Java的一个命令行工具,用于生成JNI(Java Native Interface)的C或C++头文件。这些头文件包含了Java方法的本地签名,允许C或C++代码调用这些方法。当你需要编写本地代码来实现Java方法时,javah生成的头文件是非常有用的。
假设你有一个Java类MyClass,它位于包org.example中,并且你想要为这个类生成JNI头文件。以下是你需要遵循的步骤:

  1. 编写java类
  2. 编译java类,使用javac命令编译Java源文件。这一步骤会生成.class文件,javah工具需要这些文件才能工作。如,javac org/example/MyClass.java,注意.java文件所在的路径
  3. 使用javah生成C头文件,需要指定类的全限定名(包括包名)。如,javah -jni org.example.MyClass
  4. 生成.h文件,如org_example_NativeLibrary.h

C头文件内容如下

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_example_NativeLibrary */#ifndef _Included_org_example_NativeLibrary
#define _Included_org_example_NativeLibrary
#ifdef __cplusplus
extern "C" {
#endif
/** Class:     org_example_NativeLibrary* Method:    printHello* Signature: ()V*/
JNIEXPORT void JNICALL Java_org_example_NativeLibrary_printHello(JNIEnv *, jobject);#ifdef __cplusplus
}
#endif
#endif

3、C程序文件

创建C程序文件,如NativeLibrary.c,内容如

#include <jni.h>
#include "org_example_NativeLibrary.h"JNIEXPORT void JNICALL Java_org_example_NativeLibrary_printHello(JNIEnv *env, jobject obj) {printf("Hello from C!\n");
}

其中,#include <jni.h>的jni.h文件来自jdk环境下,#include "NativeLibrary.h"来自使用javah生成的C头文件,Java_org_example_NativeLibrary_printHello需要和C头文件中的方法名称抱持一致。

4、共享库.so文件

编译C程序和头文件生成共享库,命令如下

gcc -shared -fpic -o libmylib.so -I$JAVA_HOME/include -I$JAVA_HOME/include/linux NativeLibrary.c

其中 libmylib.so为生成的共享库文件, -I J A V A H O M E / i n c l u d e − I JAVA_HOME/include -I JAVAHOME/includeIJAVA_HOME/include/linux为找C程序中的jni.h依赖,NativeLibrary.c为C程序文件,且C头文件需要和C程序文件在同一目录下。
在执行编译之前,请确保已经安装了gcc编译器,以及jdk环境。

5、运行Java程序

在linux环境中将.so共享库文件所在路径加入java.library.path中,设置环境变量,如下

export LD_LIBRARY_PATH=".so文件所在路径"
java ***类或java -jar ***包

结果类似如下
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词