Java ffm `linker.option.capturecallstate` не успешно захватывает` getlasterror` в WindowsJAVA

Программисты JAVA общаются здесь
Anonymous
Java ffm `linker.option.capturecallstate` не успешно захватывает` getlasterror` в Windows

Сообщение Anonymous »

Я пытаюсь получить getLasterRor код на loadlibraryw сбой через inoncer.option.captureCallState . В соответствии с документацией и этой проблемой в системе ошибок JDK, CaptureCallState является предпочтительным способом получения таких кодов ошибок.
MWE здесь (требуется Java 22+):

Код: Выделить всё

import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.VarHandle;

public final class Drill {
public static void main(String[] args) throws Throwable {
System.loadLibrary("kernel32");

Linker nativeLinker = Linker.nativeLinker();
SymbolLookup stdlibLookup = nativeLinker.defaultLookup();
SymbolLookup loaderLookup = SymbolLookup.loaderLookup();

MemorySegment pfnLoadLibraryW = loaderLookup.find("LoadLibraryW")
.or(() -> stdlibLookup.find("LoadLibraryW"))
.orElse(MemorySegment.NULL);

if (pfnLoadLibraryW.equals(MemorySegment.NULL)) {
throw new RuntimeException("Failed to find LoadLibraryW symbol");
}

MethodHandle hLoadLibraryW = nativeLinker.downcallHandle(
pfnLoadLibraryW,
FunctionDescriptor.of(
ValueLayout.ADDRESS, // returns HMODULE
ValueLayout.ADDRESS.withTargetLayout(ValueLayout.JAVA_SHORT) // LPCWSTR lpLibFileName
),
Linker.Option.captureCallState("GetLastError")
);

try (Arena arena = Arena.ofConfined()) {
char[] libName = "nonexist".toCharArray();
MemorySegment lpLibName = arena.allocate(ValueLayout.JAVA_SHORT, libName.length + 1);
lpLibName.copyFrom(MemorySegment.ofArray(libName));

StructLayout captureStateLayout = Linker.Option.captureStateLayout();
MemorySegment capturedState = arena.allocate(captureStateLayout);

MemorySegment result = (MemorySegment) hLoadLibraryW.invokeExact(lpLibName, capturedState);
if (!result.equals(MemorySegment.NULL)) {
throw new RuntimeException("Why would you even do this?");
}

VarHandle vh = captureStateLayout.varHandle(MemoryLayout.PathElement.groupElement("GetLastError"));
int lastError = (int) vh.get(capturedState, 0L);
System.out.println("GetLastError = " + lastError);
}
}
}
Тем не менее, захваченное поле getlasterror всегда 0 .
Я проверил это с помощью:
  • Windows11 24h2 + Oracle openjdk 24
  • windows1019 + oracle /> Windows10 LTSC2019 + Oracle OpenJDK 24
Я ошибался в случае использования CaptureCallState , или это преднамеренный дизайн или ошибка реализации JDK?

Подробнее здесь: https://stackoverflow.com/questions/796 ... re-getlast

Вернуться в «JAVA»