跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Linux 下 Java JNI 调用 .so 文件的方法

Java JNI 技术允许 Java 程序在 Linux 系统下直接调用本地 C/C++ 编译生成的 .so 动态链接库。实现过程包括编写 Java 类声明 native 方法,使用 javah 生成头文件,编写对应的 C 代码实现逻辑,并通过 gcc 编译为共享库。运行前需配置 LD_LIBRARY_PATH 环境变量或使用绝对路径加载库文件,同时需注意 jstring 类型与 C 字符串之间的正确转换以避免内存问题。

GitMaster发布于 2013/5/27更新于 2026/9/1082 浏览
Linux 下 Java JNI 调用 .so 文件的方法

Linux 下 Java JNI 调用 .so 文件的方法

刚刚试过一个这样的例子,省事起见,略改并记录如下:

1. Java 类编写
public class Hello {
    static {
        System.loadLibrary("goodluck");
    }

    public static native int get();
    public static native void set(int i, String s);

    public static void main(String[] args) {
        try {
            Hello test = new Hello();
            test.set(10, "5555");
            System.out.println(test.get());
        } catch (Exception ex) {
            System.out.println("ssssss");
        }
    }
}

OK Java 类有了。

执行:

javac Hello.java

上面成功后,再执行下面生成头文件:

javah Hello

生成了 Hello.h

2. C 语言实现

编写 Hello.c:

#include "Hello.h"

int i = 0;

JNIEXPORT jint JNICALL Java_Hello_get(JNIEnv *env, jclass jc) {
    return i;
}

JNIEXPORT void JNICALL Java_Hello_set(JNIEnv *env, jclass jc, jint j, jstring s) {
    char *tsetstr = (char *)(*env)->GetStringUTFChars(env, s, NULL); // 注意此处 jstring 和 char *的转换
    printf("%s--------\n", tsetstr);
    i = j;
}

保存,然后执行如下编译指令:

gcc -fPIC -D_REENTRANT -I/usr/java/jdk1.6.0_31/include -I/usr/java/jdk1.6.0_31/include/linux -c Hello.c
gcc -shared Hello.o -o libgoodluck.so

此时就生成了 libgoodluck.so。

注意为了让 Java 找到此 so,运行:

export LD_LIBRARY_PATH=.

将当前目录(so 文件目录,不包括文件名)加入此环境变量。

然后运行 java Hello,屏幕上打出了 10。

然后测试下传入 String 型的参数,对应的 JNI 定义应为 jstring,但却出了些问题,在显示结果时仿佛内存溢出的样子。

后来查了查,需对 jstring 和 char *作一个转换,如代码中所示,然后结果就正常。

补充说明
  1. 将编写的 Hello.c 文件编译成 .o 文件:
gcc -fPIC -D_REENTRANT -I/usr/lib/jvm/java-1.5.0-sun-1.5.0.19/include -I/usr/lib/jvm/java-1.5.0-sun-1.5.0.19/include/linux -c Hello.c

注:/usr/lib/jvm/java-1.5.0-sun-1.5.0.19/include 是 jni.h 头文件所在的路径,/usr/lib/jvm/java-1.5.0-sun-1.5.0.19/include/linux 是 jni_md.h 所在的路径。

  1. 将生成的 Hello.o 文件编译成 .so 库文件:
gcc -shared Hello.o -o libgoodluck.so

注: 和 Windows 下不同,Linux 的库文件必须是以 libxxx.so 形式命名的(或者 libxxx.so.y,y 是版本号),lib 前缀是为了系统能够识别它,xxx 是 Java 代码 System.loadLibrary("xxx"); 中引用库的名字。

将生成的 libgoodluck.so 文件拷贝到 Java 的加载库 LD_LIBRARY_PATH 指向的路径中。 前提是你有足够的权限,如果没有 sudo 权限的同学,用下面的方法:

  1. 在 /home 下建立一个用来存放 .so 库文件的目录,比如 ./jni_lib
  2. 把 libgoodluck.so 文件拷贝到该目录下
  3. 打开 Terminal,运行如下命令:
export LD_LIBRARY_PATH=./jni_lib

只在当前 shell 下有效...

另外, 以下方法可以直接利用绝对路径来 load 这个 so 库文件,从而无需做上述的放置 path 或者更改库路径的动作:

static { System.load("./jni_lib/libgoodluck.so"); }

目录

  1. Linux 下 Java JNI 调用 .so 文件的方法
  2. 1. Java 类编写
  3. 2. C 语言实现
  4. 补充说明

更多推荐文章

查看全部
  • 双向链表核心实现与算法实战解析
  • 西门子 S7-1200FC PLC 与松下机器人 Profinet 通信及外部自动控制
  • 算法基础:一维与二维前缀和详解
  • 异步编程实战:构建高性能 Python 网络应用
  • C++ 类和对象(中):默认成员函数与运算符重载
  • 秋叶绘世 Stable Diffusion 整合包与 ComfyUI 使用指南
  • Python 常用编程代码示例与详解
  • 程序员转行大模型:核心高薪岗位解析与技能要求
  • 前端高频面试题:TypeScript 核心考点与实战解析
  • 二叉树核心算法实战:深度计算与先序遍历还原
  • AI 绘画敏感内容控制:提示词策略与安全实践
  • Java 后端转 Web3 实战路线图
  • CCF-GESP 2024 年 3 月三级 C++ T2 完全平方数解题思路
  • Cursor Composer Agent 详解:多 Agent 协作完成复杂项目
  • 2026 年 4 款会议纪要工具深度测评:AI 辅助整理
  • 基于 AI 提示词的电商产品详情页高效撰写指南
  • C++ 多态:概念、实现与底层原理详解
  • 基于 Apache POI 实现高德 POI 分类数据导入 PostgreSQL
  • 打造高效的 LLM 多智能体系统:AgentPrune 通信剪枝优化
  • AIGC 音频平台强制水印策略与 AudioSeal 实现方案

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online