You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JNA调用AMD ADL Overdrive5 API遇空指针错误求助

解决JNA调用AMD ADL Overdrive5 API获取GPU温度返回空指针(-9)的问题

看起来你在JNA调用AMD ADL Overdrive5 API获取GPU温度时遇到了空指针错误(返回ADL_ERR_NULL_POINTER),我之前也踩过类似的JNA结构体映射的坑,给你几个关键的排查点和解决方案:

1. 确保JNA结构体映射完全匹配C定义

ADL的ADLTemperature结构体在C中是两个int字段,你的JNA结构体定义必须严格匹配内存布局,尤其是字段顺序——这是最容易踩的坑。

正确的结构体定义应该是这样的:

import com.sun.jna.Structure;
import java.util.Arrays;
import java.util.List;

public class ADLTemperature extends Structure {
    // 定义ByReference类,用于传递结构体指针给C API
    public static class ByReference extends ADLTemperature implements Structure.ByReference {}

    public int iTemperature; // 温度值,单位为0.1摄氏度
    public int iSensorType;  // 传感器类型,比如ADL_OVERDRIVE5_TEMPERATURE_GPU

    @Override
    protected List<String> getFieldOrder() {
        // 必须和C结构体的字段顺序完全一致!
        return Arrays.asList("iTemperature", "iSensorType");
    }
}

注意:一定要重写getFieldOrder()方法(或使用@FieldOrder注解),否则JNA会按字段名的字母顺序排列内存,导致C API拿到的是错误的内存区域,触发空指针错误。

2. 传递结构体指针而非值给API

ADL的ADL_Overdrive5_Temperature_Get函数要求传入ADLTemperature*(结构体指针),如果直接传递ADLTemperature对象,JNA会默认按值传递(复制结构体),这相当于给C API传了一个临时副本的地址,而不是可写入的结构体指针,必然触发空指针错误。

你需要在JNA的ADL库接口中定义函数时,指定参数为ADLTemperature.ByReference:

import com.sun.jna.Library;
import com.sun.jna.Pointer;

public interface ADLLibrary extends Library {
    // 注意最后一个参数是ByReference类型
    int ADL_Overdrive5_Temperature_Get(
        Pointer context, 
        int iAdapterIndex, 
        int iThermalControllerIndex, 
        ADLTemperature.ByReference pTemperature
    );
    // 其他ADL API函数定义...
}

调用时创建ByReference实例并传入:

// 假设已经初始化好ADL上下文context,且adapterIndex是有效的适配器索引
ADLTemperature.ByReference tempRef = new ADLTemperature.ByReference();
int result = adlLibrary.ADL_Overdrive5_Temperature_Get(context, adapterIndex, 0, tempRef);

if (result == 0) { // ADL_OK表示调用成功
    float gpuTemp = tempRef.iTemperature / 10.0f; // 转换为摄氏度
    System.out.println("GPU温度: " + gpuTemp + "°C");
} else {
    System.err.println("获取温度失败,错误码: " + result);
}

3. 检查其他参数的有效性

虽然错误码是空指针,但也可以快速确认:

  • iThermalControllerIndex:通常GPU的温度控制器索引是0,部分显卡可能有多个控制器(比如0是GPU、1是显存),可以尝试传入0或1测试。
  • ADL上下文:确保context是初始化后有效的指针,没有被提前释放(你已经能获取适配器信息,这一步大概率没问题,但可以再确认)。

4. 确认Overdrive功能已启用

部分ADL温度相关API需要先调用ADL_Overdrive5_Enable启用Overdrive功能,否则可能返回错误。如果前面的步骤都没问题,可以尝试先调用该函数:

// 启用适配器index的Overdrive功能
int enableResult = adlLibrary.ADL_Overdrive5_Enable(context, adapterIndex, 1);
if (enableResult != 0) {
    System.err.println("启用Overdrive失败,错误码: " + enableResult);
}

内容的提问来源于stack exchange,提问作者Volker Pfeffer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:24:56