Java JNA WinAPI函数使JVM静默崩溃

时间:2018-09-20 15:07:20

标签: java winapi jvm jna

我正在尝试使用jna从Java调用winapi函数CallNtPowerInformation

这是我的代码:

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 :(得分:3)

您正在传递Java数组中第一个Structure的地址,该Java数组是由不同的Structure实例构造而成的。被调用方希望有一个连续的内存块,而您只传递了单个结构大小的块,却告诉被调用方N个结构的大小。

使用Structure.toArray()获取一块连续分配的内存。然后,您可以根据需要操纵数组的成员。调用之后,JNA应该自动更新数组的所有成员。