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
相关产品推荐
相关产品推荐

