千家信息网

Linux系统中如何使用JNI

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章将为大家详细讲解有关Linux系统中如何使用JNI,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。JNI是Java Native Interface的缩写,通
千家信息网最后更新 2026年11月01日Linux系统中如何使用JNI

这篇文章将为大家详细讲解有关Linux系统中如何使用JNI,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

JNI是Java Native Interface的缩写,通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交。

我将详细说明在 Linux 平台下如何实现本地共享库与 Java 协同工作,老规矩以Hello world为例。

定义一个 Java 类 — Hello类

public class Hello{ static {  try  {// 此处即为本地方法所在链接库名   System.loadLibrary("hello");  }  catch(UnsatisfiedLinkError e)  {   System.err.println( "Cannot load hello library:\n " +                               e.toString() );  } } public Hello() { }// 声明的本地方法  public native void SayHello(String strName);}

这里有两个注意事项:

首先:为要使用的每个本地方法编写本地方法声明,只是必须指定 native 关键字,如下所示:

public native void SayHello(String strName);

其次:必须显式地加载本地代码库。我们需在类的静态块中加载这个库(静态库在类加载时候就会调用)

现在我们来编辑hello.java以生成hello.class文件。

生成本地链接库

要为以上定义的类生成 Java 本地接口头文件,需使用 javah,Java 编译器的 javah 功能将根据 Hello 类生成必要的声明,此命令将生成 Hello.h 文件

生成的 Hello.h 文件 内容如下所示:

#include  /* Header for class Hello */#ifndef _Included_Hello#define _Included_Hello#ifdef __cplusplusextern "C" {#endif/** Class:     Hello* Method:    SayHello* Signature: (Ljava/lang/String;)V*/JNIEXPORT void JNICALL Java_Hello_SayHello (JNIEnv *, jobject, jstring);#ifdef __cplusplus}#endif#endif

在与 Hello.h 相同的路径下创建一个 CPP 文件 Hello.cpp

内容如下:

#include "Hello.h"#include  // 与 Hello.h 中函数声明相同JNIEXPORT void JNICALL Java_Hello_SayHello  (JNIEnv * env, jobject arg, jstring instring){  // 从 instring 字符串取得指向字符串 UTF 编码的指针const jbyte *str =       (const jbyte *)env->GetStringUTFChars( instring, JNI_FALSE );   printf("Hello,%s\n",str); // 通知虚拟机本地代码不再需要通过 str 访问 Java 字符串。   env->ReleaseStringUTFChars( instring, (const char *)str );   return;}

这里有三个参数,下面讲一下参数用法:

(1)所有的 JNI 调用都使用了 JNIEnv * 类型的指针,习惯上在 CPP 文件中将这个变量定义为 evn,它是任意一个本地方法的第一个参数。env 指针指向一个函数指针表,在 VC 中可以直接用"->"操作符访问其中的函数。 (2)jobject 指向在此 Java 代码中实例化的 Java 对象 LocalFunction 的一个句柄,相当于 this 指针。 (3)第三个参数就是本地调用中有 Java 程序传进的参数,本例中只有一个 String 型参数。 对于字符串型参数,因为在本地代码中不能直接读取 Java 字符串,而必须将其转换为 C /C++ 字符串或 Unicode。

编译生成共享库。

使用 GCC 时 , 必须通知编译器在何处查找此 Java 本地方法的支持文件,并且显式通知编译器生成位置无关的代码,在我的环境中按如下过程编译:

gcc -I/home/jbuilder/jdk1.3.1/include   -I/home/jbuilder/jdk1.3.1/include/linux -fPIC -c Hello.c

生成 Hello.o

gcc -shared -Wl,-soname,libhello.so -o libhello.so Hello.o

生成 libhello.so(这就是linux下动态链接库的文件名格式,就像windows下是.dll文件后缀名类似)

最后通知动态链接程序此共享文件的路径。

export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH

编写一个简单的 Java 程序来测试我们的本地方法

将如下源码存为 A.java:

import Hello;import java.util.*;public class A{ public static void main(String argv[]) {  A a = new A(); } public A() {  Hello h = new Hello();  // 调用本地方法  h.SayHello("Hello world");     }}

用 javac 编译A.java,生成A.class 向执行普通 Java 程序一样使用 java A,我们会看到在屏幕上出现 Hello world。 ok,完成!

关于"Linux系统中如何使用JNI"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

生成 文件 代码 方法 参数 字符 字符串 编译 指针 程序 链接 内容 函数 平台 指向 篇文章 编译器 系统 相同 三个 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 湖北九亚互联网络科技有限公司 中关村互联网科技集团 互联网最新的科技有限公司 上海挚品互联网科技 杭州互联网科技公司 深圳期待互联网科技 亿人帮互联网科技 科技互联网创业计划书 中国科技互联网公司收入 中国的互联网科技企业的崛起 互联网科技寓意 欧洲十大科技互联网公司 互联网金融中的现代科技 浙江互联网科技研学营 武汉健翔互联网络科技有限公司 赶超互联网科技 微信多开 崇明区互联网教育科技售后服务 互联网科技的全部知识 互联网数据科技专业 数字科技和互联网金融哪个好 极限挑战互联网科技 博兴的互联网电子科技公司 互联网汽车科技小镇 团飞科技与伯堂互联网服务平台 广州新华互联网科技学校电竞方面 富国互联网金融科技混合基金 半导体行业属于互联网高科技类吗 广州梦谷互联网科技有限公司领导 杭州融税互联网科技有限公司 青岛易易互联网科技
0