JNI调用.a静态库

本文详细介绍了JNI的作用,展示了如何在Ubuntu上通过JNI调用静态库,并指导了从JNI头文件创建到实际调用静态库方法的步骤。此外,还提供了参考文档链接帮助进一步学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文介绍了JNI的基本用法以及如何将.a静态库二次封装成.so动态库供JNI调用等内容。

什么是JNI?

JNI全称为Java Native Interface,是Java提供的一套和不同平台native交互(或者说调用native)的接口。意味着你可以通过JNI在Windows平台上调用.DLL或者在Linux(Centos/Ubuntu/Android)平台上调用.so,至于.DLL和.so是什么此处不再赘述,读者可自行查阅有关资料。

如何使用?

这里以Ubuntu为例,介绍如何使用JNI调用.a静态库(将.a静态库封装成为.so库供JNI调用)

①新建一个Java文件JT.java并声明native方法call

import java.lang.String;
import java.lang.System;

public class JT{
  public native void call(); // native方法

  public static void main(String[] args) { //Java入口
    System.out.println("java in...");
    new JT().call();
    System.out.println("java out..");
  }
  static {
    System.loadLibrary("demo"); //加载libdemo.so
  }
}

②生成头文件
命令行切换到JT.java所在目录,依次执行以下命令:

javac JT.java

上述命令用于生成JT.java的字节码文件

javah JT

上述命令用于生成JNI头文件,这里生成的头文件为JT.h

③实现头文件中声明的方法
这里首先要对头文件进行完善,头文件中声明的方法只有参数类型,没有参数名称,这里需要手动补全(这里作者补全了envobj,如果还有其它参数,同理补全)

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JT */

#ifndef _Included_JT
#define _Included_JT
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JT
 * Method:    call
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JT_call
  (JNIEnv * env, jobject obj);

#ifdef __cplusplus
}
#endif
#endif

然后需要模拟一个静态库,这里为welcome库,它包含一个welcome.h(方法声明)和一个welcome.c(方法实现),具体代码如下:
welcome.h

#ifndef _WELCOME_H
#define _WELCOME_H

void welcome();

#endif

welcome.c

#include<stdio.h>
#include"welcome.h"

void welcome()
{
    printf("welcome, this is static library\n");
}

然后编译生成welcome.a静态库:

gcc -Wall -O2 -fPIC -I./  -c -o welcome.o welcome.c
ar crv libwelcome.a welcome.o

有了静态库之后,开始编写demo.c,实现JNI方法并调用welcome.a静态库中的welcome方法:

#include<stdio.h>
#include"JT.h"
#include"welcome.h"

/*
 * Class:     JT
 * Method:    call
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JT_call
  (JNIEnv * env, jobject obj) {
  printf("hello, demo!\n");
  welcome(); //welcome.a
}

然后编译demo.c生成demo.o

gcc -Wall -O2 -fPIC -I /opt/jdk1.8.0_321/include/ -I /opt/jdk1.8.0_321/include/linux/ -I./  -c -o demo.o demo.c

再将demo.owelcome.a封装成为libdemo.so

gcc -shared demo.o -L. -lwelcome -o libdemo.so

④通过Java调用

java -Djava.library.path=./ JT

这里需要通过-Djava.library.path参数指定了共享库的路径,否则默认会报错,找不到共享库libdemo.so,再来看看输出:

java in...
hello, demo!
welcome, this is static library
java out..

目录及文件结构如下:

.
├── demo.c
├── demo.o
├── jni.h
├── JT.class
├── JT.h
├── JT.java
├── libdemo.so
├── libwelcome.a
├── welcome.c
├── welcome.h
└── welcome.o

参考文档

1.Oracle JNI文档,此文档介绍了Oracle JNI的一些规范、动态库和静态库的区别及注意事项和高级特性。

2.JNA调用.a静态库,此blog介绍了如何通过JNA调用so动态库,以及如何将.a静态库封装成为.so动态库供JNA调用。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值