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();

  因为改变了方案,此路没通,也没再继续研究路。此处仅做记录。

posted @ 2024-01-14 17:28  badwood  阅读(8)  评论(0编辑  收藏  举报
Badwood's Blog