java与C配合
虽然没有完成全部过程,最后卡在调用时报错,但还是记录下过程:
1、创建java类,声明native方法
package com.example.gpumonitor; public class GPUMonitor { static { System.loadLibrary("gpumonitor"); // 加载对应平台的动态链接库 } public native String getGPUUsage(); // 声明native方法 public static void main(String[] args) { GPUMonitor monitor = new GPUMonitor(); String gpuUsage = monitor.getGPUUsage(); System.out.println("GPU Usage: " + gpuUsage); } }
2、编译java类,会有.class文件生成
javac GPUMonitor.java
3、生成jni头文件,可以通过maven直接打包生成,增加红色字体的配置,会在include目录下生成GPUMonitor.h文件。用javah(老sdk)或java(新sdk)没有成功。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <!-- 使用当前稳定版本 --> <configuration> <compilerArguments> <h>target/native/include</h> <!-- 指定头文件输出目录 --> </compilerArguments> <source>1.8</source> <target>1.8</target> </configuration> </plugin>
4、创建C文件,编写native方法。编译的时候可能需要指定jni.h的位置:
#include "GPUMonitor.h" #include <jni.h> #include <stdio.h> #include <string.h> JNIEXPORT jstring JNICALL Java_com_example_gpumonitor_GPUMonitor_getGPUUsage(JNIEnv *env, jobject obj) {{ char command[100] = "nvidia-smi"; FILE* pipe = popen(command, "r"); if (!pipe) return (*env)->NewStringUTF(env,"Failed to run command"); char buffer[128]; char result[4096] = ""; while(fgets(buffer, 128, pipe) != NULL) { strncat(result, buffer, sizeof(buffer) - 1); } pclose(pipe); return (*env)->NewStringUTF(env,result); }
5、编译、链接C代码,linux下生成so文件。可能需要指定jni.h的位置,带上-I参数。
gcc -I/usr/lib/jvm/java-1.8.0-openjdk-1.8/include -I/usr/lib/jvm/java-1.8.0-openjdk-1.8/include/linux -shared -fPIC -o gpumonitor.so GPUMonitor.c
6、在java中调用C的so库,可惜到这一步报错,说找不到类
GPUMonitor monitor = new GPUMonitor();
String gpuUsage = monitor.getGPUUsage();
因为改变了方案,此路没通,也没再继续研究路。此处仅做记录。