# jni **Repository Path**: xieshaoping/jni ## Basic Information - **Project Name**: jni - **Description**: linux环境下,java调用c语言的方法 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-03-10 - **Last Updated**: 2022-03-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # windows环境下,java调用c语言的方法 ## 1.环境 * C语言编译器:工具比较多,本文使用的是gcc,带gcc的软件业比较丰富,我使用的是TDM-GCC, 注:网上很多使用的是MinGW,但我遇到了很多坑,最终在联想软件商店中下载的TDM-GCC,nice * java环境 ## 2.编写native方法java工具类,主要负责与本地native方法链接,不负责业务逻辑 ```java package com.xieshaoping.jni; /** * @author XieShaoping */ public class NativeEntity { public native String getNativeMsg(); public NativeEntity(String filename) { System.load(filename); } } ``` ## 3.编写调用native方法java的类,主要负责业务逻辑 ```java package com.xieshaoping.jni; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author XieShaoping */ @RestController public class LoadlibraryController { @RequestMapping("loadlibrary") public String loadlibrary(String lib) { NativeEntity nativeEntity = new NativeEntity(lib); String msg = nativeEntity.getNativeMsg(); System.out.println(msg); return msg; } } ``` ## 4.编译java生产class ```shell javac NativeEntity.java ``` ## 5.使用javah生成标头文件 ```shell javah -jni com.xieshaoping.jni.NativeEntity ``` 注:直接输入javah -jni NativeEntity时会报错的,因为java有page的概念,需要在根目录下运行上述,命令 此时生产了com_xieshaoping_jni_NativeEntity.h文件 ## 编写C语言 ```c #include #include #include #include #include //linux下,需要注释 #include "com_xieshaoping_jni_NativeEntity.h" JNIEXPORT jstring JNICALL Java_com_xieshaoping_jni_NativeEntity_getNativeMsg(JNIEnv* env, jobject obj) //一定要与.h里的保持一致 { //打印内容 char *msg = "正在调用本地本地native方法-windows"; printf(msg); //char * 转为jstring jclass strClass = (*env)->FindClass(env, "java/lang/String"); jmethodID ctorID = (*env)->GetMethodID(env, strClass, "","([BLjava/lang/String;)V"); jbyteArray bytes = (*env)->NewByteArray(env, strlen(msg)); (*env)->SetByteArrayRegion(env, bytes, 0, strlen(msg), (jbyte *) msg); jstring encoding = (*env)->NewStringUTF(env, "utf-8"); return (jstring) (*env)->NewObject(env, strClass, ctorID, bytes, encoding); } ``` ## 7.gcc生成类库文件 ```shell gcc -m64 -Wl,--add-stdcall-alias -I"D:\MyTool\Java\jdk1.8.0_251\include" -I"D:\MyTool\Java\jdk1.8.0_251\include\win32" -shared WindowsNative.c ``` -m64 生成64位 -o 命名,默认a.exe ## 8.运行程序 ```http request http://localhost:8080/loadlibrary?lib=D%3A%5CMyProject%5Cjni%5Csrc%5Cmain%5Cjava%5Ccom%5Cxieshaoping%5Cjni%5Ca.exe ``` 显示C语言方法输出的内容 ![img.png](img.png) # linux环境下,java调用c语言的方法 与windows大部分相同, 不同处: * 删除“#include ” * 添加java环境变量 ```shell export JAVA_HOME=/root/jdk1.8.0_311 export PATH=$PATH:$JAVA_HOME/bin export CLASSPATH=.:$JAVA_HOME/lib ``` * gcc生成类库文件 ```shell gcc -I"/root/jdk1.8.0_311/include" -I"/root/jdk1.8.0_311/include/linux" -fPIC -shared LinuxNative.c ``` 默认生成a.out文件 运行成功 ![img_1.png](img_1.png) 大功告成!