Java JNA WinAPI 函数静默崩溃 JVM
Java JNA WinAPI function crash silently the JVM
我正在尝试使用 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(堆损坏)。
也许我遗漏了什么?
您正在传递 Java 数组中第一个 Structure
的地址,该数组由不同的 Structure
实例构造而成。被调用者需要一个连续的内存块,而您只传递一个大小为单个结构的块,但告诉被调用者它是 N 个结构的大小。
使用Structure.toArray()
获取一块连续分配的内存。然后,您可以根据需要操作数组的成员。 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(堆损坏)。
也许我遗漏了什么?
您正在传递 Java 数组中第一个 Structure
的地址,该数组由不同的 Structure
实例构造而成。被调用者需要一个连续的内存块,而您只传递一个大小为单个结构的块,但告诉被调用者它是 N 个结构的大小。
使用Structure.toArray()
获取一块连续分配的内存。然后,您可以根据需要操作数组的成员。 JNA 应在调用后自动更新数组的所有成员。