Search code examples
javajna

JNA - AMD Overdrive5 API returns null pointer error


I am trying to access the AMD ADL Overdrive5 API via JNA to retrieve temperatures of the GPU in JAVA. I am able to retrieve the adapter information via the ADL API. But I am having a hard time to retrieve the GPU Temperatures.

The API function is defined as:

int ADL2_Overdrive5_Temperature_Get (
    ADL_CONTEXT_HANDLE context,
    int iAdapterIndex,
    int iThermalControllerIndex,
    ADLTemperature * lpTemperature   
)   

and expects a Pointer to a structure containing two ints.

The code I have is:

public interface ADL extends Library {

    public static class T1Str extends Structure {
        public static class ByReference extends T1Str implements Structure.ByReference {}

        public int iSize;
        public int iTemperature;

        @Override
        protected List<String> getFieldOrder() {
            re  turn ImmutableList.of(
                "iSize",
                "iTemperature"
            );
        }
    }

    public int ADL_Overdrive5_Temperature_Get(
        Pointer context,
        int     iAdapterIndex,
        int     iThermalControllerIndex,
        T1Str.ByReference pointer 
    );

}

The actual call of the function is:

final T1Str.ByReference str = new T1Str.ByReference();
str.iSize = str.size();
final int result = adl.ADL_Overdrive5_Temperature_Get(
    context,
    adapterIndex,
    0,
    str
);

The call always returns -9 as a result which translates into ADL_ERR_NULL_POINTER: Null Pointer error

Any help is appreciated.


Solution

  • Looking at the documentation, it appears that there's two different, confusingly similarly named functions:

    int ADL_Overdrive5_Temperature_Get(
        int iAdapterIndex,
        int iThermalControllerIndex,
        ADLTemperature *lpTemperature
    )
    

    ...and...

    int ADL2_Overdrive5_Temperature_Get(
        ADL_CONTEXT_HANDLE context,
        int iAdapterIndex,
        int iThermalControllerIndex,
        ADLTemperature *lpTemperature
    )
    

    As you've probably realized by now, you're accidentally calling the first one whereas you meant to call the second one. Since you pass 0 for the third argument of the first function, you're essentially passing NULL for the pointer argument.

    Include the number 2 in your Java method's name to call the correct function.

    public int ADL2_Overdrive5_Temperature_Get(
        Pointer context,
        int iAdapterIndex,
        int iThermalControllerIndex,
        T1Str.ByReference pointer 
    );
    

    By the way, if I recall correctly, JNA passes structure arguments ByReference by default so you can save some verbosity by just using the T1Str class as the the argument's type.