Функция Java JNA WinAPI автоматически завершает работу JVM - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь вызвать функцию winapi CallNtPowerInformation из java с jna.

Это мой код:

NativeProcessorPowerInformation[] systemProcessors = new NativeProcessorPowerInformation[getProcessorCount()];
for (int systemProcessorIndex = 0; systemProcessorIndex < systemProcessors.length; systemProcessorIndex++) {
    systemProcessors[systemProcessorIndex] = new NativeProcessorPowerInformation();
}

nativeLibraryPowrprof.CallNtPowerInformation(11, null, new NativeLong(0),
    systemProcessors[0], new NativeLong(systemProcessors.length * systemProcessors[0].size())
);

DLL создается с этим:

nativeLibraryPowrprof = Native.loadLibrary("powrprof", NativeLibraryPowrprof.class, W32APIOptions.DEFAULT_OPTIONS);

И это интерфейс библиотеки, который я использовал:

public static interface NativeLibraryPowrprof extends StdCallLibrary {
    public int CallNtPowerInformation(int informationLevel, Pointer lpInputBuffer, NativeLong nInputBufferSize, Structure lpOutputBuffer, NativeLong nOutputBufferSize);

    @ToString
    public static class NativeProcessorPowerInformation extends Structure {
        public ULONG Number;
        public ULONG MaxMhz;
        public ULONG CurrentMhz;
        public ULONG MhzLimit;
        public ULONG MaxIdleState;
        public ULONG CurrentIdleState;

        @Override
        protected List<String> getFieldOrder() {
            return Arrays.asList("Number", "MaxMhz", "CurrentMhz", "MhzLimit", "MaxIdleState", "CurrentIdleState");
        }
    }
}

Этот код работает (в течение 10 секунд), результаты исправляются, но иногда через 10/20 секунд происходит сбойJVM молча, я получаю код выхода -1073740940 (повреждение кучи).

Может быть, я что-то упустил?

1 Ответ

0 голосов
/ 20 сентября 2018

Вы передаете адрес первого Structure в массиве Java, который был создан из разрозненных Structure экземпляров.Вызываемый ожидает непрерывный блок памяти, и вы только передаете блок размером с одну структуру, но сообщаете вызываемому объекту, что это размер N структур.

Используйте Structure.toArray(), чтобы получить блок непрерывновыделенная память.Затем вы можете манипулировать членами массива, если это необходимо.JNA должен автоматически обновлять все элементы массива после вызова.

...