JAVA?JNA調(diào)用C接口的三種實現(xiàn)方式
1. 準備一個共享庫文件
test.c
#include <stdio.h>
int test(char *input){
printf("input:%s\n",input);
return 0;
}libtest.so
[root@node-126 ~]# gcc -fPIC -shared -o libtest.so test.c [root@node-126 ~]# ls /root/ anaconda-ks.cfg libtest.so node-v6.10.2-linux-x64.tar.xz original-ks.cfg spring3 test test.c
可以看到有test方法
[root@node-126 ~]# nm -D libtest.so
0000000000201038 B __bss_start
w __cxa_finalize
0000000000201038 D _edata
0000000000201040 B _end
0000000000000600 T _fini
w __gmon_start__
00000000000004c0 T _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
U printf
00000000000005d5 T test2. JNA方式1—繼承Library接口
建個普通maven項目
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.5.0</version>
</dependency>package jna;
import com.sun.jna.Library;
import com.sun.jna.Native;
/**
* 接口繼承
*
* @author majun
* @version 1.0
* @since 2023-08-22 22:27
*/
public interface MyClibrary extends Library {
MyClibrary INSTANTCE = Native.load("/root/libtest.so", MyClibrary.class);
int test(String input);
}測試
import jna.MyClibrary;
/**
* TODO
*
* @author majun
* @version 1.0
* @since 2023-03-31 7:44
*/
public class Main {
public static void main(String[] args) {
int test = MyClibrary.INSTANTCE.test("extend Library");
System.out.println(test);
}
}
使用Linux上的Java運行

3. JNA方式2—直接NativeLibrary.getInstance
import com.sun.jna.Function;
import com.sun.jna.NativeLibrary;
/**
* TODO
*
* @author majun
* @version 1.0
* @since 2023-03-31 7:44
*/
public class Main {
public static void main(String[] args) {
NativeLibrary instance = NativeLibrary.getInstance("/root/libtest.so");
Function func = instance.getFunction("test");
Object res = func.invoke(Integer.class, new Object[]{"NativeLibrary.getInstance"});
System.out.println( res);
}
}
4. JNA方式3—Native方法
mkdir -p /root/jna && cd /root/jna 新建MyNative.java
package jna;
import java.io.IOException;
public class MyNative {
native int test(String input) throws IOException;
}
編譯并生成頭文件(這里java17沒找到j(luò)avah命令,改用java8的,但注意javac ,javah要使用同一個Java版本的)
/usr/local/jdk1.8.0_111/bin/javac MyNative.java /usr/local/jdk1.8.0_111/bin/javah -classpath /root/ -jni jna.MyNative
linux直接編輯實現(xiàn)頭文件中的接口:
#include <stdio.h>
#include <jni.h>
#include "jna_MyNative.h"
jint Java_jna_MyNative_test(JNIEnv *jniEnv, jobject clazz, jstring input){
printf("input:%s\n",(char *)input);
return 0;
}
編譯時注意引入jdk頭文件包下的jni.h等
gcc -fPIC -shared -I/usr/lib/jvm/jdk-17-oracle-x64/include -I/usr/lib/jvm/jdk-17-oracle-x64/include/linux -o libtest.so test.c
使用Clion實現(xiàn)頭文件的接口:新建C項目,引入jna_MyNative.h,并實現(xiàn)其中的方法

注意:
1.使用遠程toolchain,cmake編譯安裝運行,注意cmake版本可能導致include_directories(SYSTEM "/usr/lib/jvm/jdk-17-oracle-x64/include") 同步Linux上jdk的頭文件失敗,本地無法找到符號,但可以正常運行。
2.jniEnv必須Java調(diào)用才會有值。
cmake_minimum_required(VERSION 2.8) project(untitled1) set(CMAKE_CXX_STANDARD 17) include_directories(SYSTEM "/usr/lib/jvm/jdk-17-oracle-x64/include") include_directories(SYSTEM "/usr/lib/jvm/jdk-17-oracle-x64/include/linux") add_executable(testexe main.cpp) add_library(test SHARED main.cpp jna_MyNative.h) target_link_libraries(test -I/usr/lib/jvm/jdk-17-oracle-x64/include -I/usr/lib/jvm/jdk-17-oracle-x64/linux) install(TARGETS test LIBRARY DESTINATION /usr/lib)
Java調(diào)用測試
import jna.MyNative;
import java.io.IOException;
/**
* TODO
*
* @author majun
* @version 1.0
* @since 2023-08-23 23:44
*/
public class Main {
public static void main(String[] args) throws IOException {
System.load("/root/jna/libtest.so");
//System.loadLibrary("test");// 自動拼接成libtest.so,默認從/usr/lib,/usr/lib64等路徑找
MyNative myNative = new MyNative();
int test = myNative.test("native");
System.out.println(test);
}
}
姿勢3實現(xiàn)的C接口,Java依舊可以使用姿勢1,2的方式來調(diào)用,注意函數(shù)名為Java_jna_MyNative_test
[root@node-126 lib]# nm -D /usr/lib/libtest.so
0000000000201070 B __bss_start
U __cxa_allocate_exception
w __cxa_finalize
U __cxa_free_exception
U __cxa_throw
0000000000201070 D _edata
0000000000201078 B _end
0000000000000b4c T _fini
w __gmon_start__
U __gxx_personality_v0
0000000000000860 T _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000000a15 T Java_jna_MyNative_test
w _Jv_RegisterClasses
0000000000000ac8 T main
U printf
U _Unwind_Resume
0000000000000b18 W _ZN7JNIEnv_8ThrowNewEP7_jclassPKc
0000000000000aea W _ZN7JNIEnv_9FindClassEPKc
U _ZTIi總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用ElasticSearch6.0快速實現(xiàn)全文搜索功能的示例代碼
本篇文章主要介紹了使用ElasticSearch6.0快速實現(xiàn)全文搜索功能,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-02-02
SpringBoot集成Serverless的實現(xiàn)示例
本文主要介紹了SpringBoot集成Serverless的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2026-04-04
Java泛型模擬scala實現(xiàn)自定義ArrayList方式
這篇文章主要介紹了Java泛型模擬scala實現(xiàn)自定義ArrayList方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
關(guān)于Spring MVC框架中攔截器Interceptor的使用解讀
這篇文章主要介紹了關(guān)于Spring MVC框架中攔截器Interceptor的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
關(guān)于java自定義線程池的原理與實現(xiàn)
本文介紹了如何自定義線程池和阻塞隊列,包括阻塞隊列的實現(xiàn)方法,線程池的構(gòu)建以及拒絕策略的應用,詳細闡述了線程池中任務的提交和執(zhí)行流程,以及如何處理任務超出隊列容量的情況2022-04-04

