Układy pamięci i struktury
Opisywanie układów pamięci natywnej
Układy pamięci i struktury to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.
Opisywanie pamięci natywnej
Dane natywne rzadko składają się z pojedynczej wartości. W języku C używa się struktur, tablic i unii. FFM odwzorowuje te kształty za pomocą layoutów pamięci, umożliwiając bezpieczny odczyt i zapis struktury pamięci natywnej.
Rodzina layoutów
Typy layoutów tworzą niewielką hierarchię:
ValueLayout: typ podstawowy (int, long, double, address)SequenceLayout: tablica layoutu o stałym rozmiarzeStructLayout: pola ułożone sekwencyjnieUnionLayout: nakładające się pola
Layout wartości
Najprostsze layouty to wbudowane layouty wartości. Zawierają informacje o rozmiarze, wyrównaniu i kolejności bajtów.
import java.lang.foreign.ValueLayout;
public class Main {
public static void main(String[] args) {
System.out.println("int size: " + ValueLayout.JAVA_INT.byteSize());
System.out.println("double size: " + ValueLayout.JAVA_DOUBLE.byteSize());
}
}Definiowanie struktury
Modelowanie struktury C odbywa się za pomocą MemoryLayout.structLayout(...), a nazwy poszczególnych pól nadaje się przez withName. Rozważmy strukturę C struct Point { int x; int y; }.
import java.lang.foreign.*;
public class Main {
public static void main(String[] args) {
StructLayout point = MemoryLayout.structLayout(
ValueLayout.JAVA_INT.withName("x"),
ValueLayout.JAVA_INT.withName("y"));
System.out.println("Point size: " + point.byteSize());
}
}VarHandle dla pól
Aby odczytać nazwane pole lub zapisać do niego wartość, należy wyprowadzić obiekt VarHandle za pomocą wyrażenia ścieżki. groupElement("x") wybiera pole na podstawie jego nazwy.
import java.lang.foreign.*;
import java.lang.invoke.VarHandle;
public class Main {
public static void main(String[] args) {
StructLayout point = MemoryLayout.structLayout(
ValueLayout.JAVA_INT.withName("x"),
ValueLayout.JAVA_INT.withName("y"));
VarHandle xHandle = point.varHandle(
MemoryLayout.PathElement.groupElement("x"));
System.out.println("Built VarHandle for x: " + xHandle);
}
}Odczyt i zapis struktury
Należy przydzielić segment o rozmiarze określonym przez layout, a następnie użyć uchwytów var do ustawiania i pobierania pól. Odzwierciedla to wypełnianie struktury C.
import java.lang.foreign.*;
import java.lang.invoke.VarHandle;
public class Main {
public static void main(String[] args) {
StructLayout point = MemoryLayout.structLayout(
ValueLayout.JAVA_INT.withName("x"),
ValueLayout.JAVA_INT.withName("y"));
VarHandle xh = point.varHandle(MemoryLayout.PathElement.groupElement("x"));
VarHandle yh = point.varHandle(MemoryLayout.PathElement.groupElement("y"));
try (Arena arena = Arena.ofConfined()) {
MemorySegment p = arena.allocate(point);
xh.set(p, 0L, 3);
yh.set(p, 0L, 4);
System.out.println("Point = (" + xh.get(p, 0L) + ", " + yh.get(p, 0L) + ")");
}
}
}Dopełnianie i wyrównanie
Kompilatory C wstawiają dopełnienie, aby pola były prawidłowo wyrównane. FFM nie dodaje go automatycznie, dlatego trzeba uwzględnić MemoryLayout.paddingLayout(n), aby dokładnie odwzorować layout C.
Nieprawidłowe wyrównanie powoduje uszkodzenie każdego pola znajdującego się za luką.
Przykład jawnego dopełnienia
W przypadku struct { char c; int n; } wartość typu int musi być wyrównana do 4 bajtów, dlatego po wartości char występują 3 bajty dopełnienia.
import java.lang.foreign.*;
public class Main {
public static void main(String[] args) {
StructLayout s = MemoryLayout.structLayout(
ValueLayout.JAVA_BYTE.withName("c"),
MemoryLayout.paddingLayout(3),
ValueLayout.JAVA_INT.withName("n"));
System.out.println("Aligned struct size: " + s.byteSize());
}
}Layouty sekwencji
Obiekt SequenceLayout opisuje tablicę. MemoryLayout.sequenceLayout(count, element) może na przykład odwzorowywać tablicę 10 wartości typu double.
import java.lang.foreign.*;
public class Main {
public static void main(String[] args) {
SequenceLayout arr = MemoryLayout.sequenceLayout(10, ValueLayout.JAVA_DOUBLE);
System.out.println("Array bytes: " + arr.byteSize());
}
}Zagnieżdżone layouty
Layouty można łączyć. Struktura może zawierać sekwencję, a sekwencja może zawierać struktury. Wyrażenia ścieżek, takie jak sequenceElement() i groupElement(name), umożliwiają nawigowanie po głęboko zagnieżdżonych danych.
Pozwala to obsługiwać rzeczywiste struktury danych C o dowolnej złożoności.
Przesunięcia i wycinanie
Można pobrać właściwość byteOffset pola na podstawie jego ścieżki i użyć segment.asSlice(offset, size), aby uzyskać podsegment. Jest to przydatne, gdy trzeba przekazać pojedyncze pole struktury do funkcji natywnej.
Szybkie sprawdzenie
Proszę przypomnieć sobie częsty problem związany ze strukturami.
Podsumowanie
Dowiedzieli się Państwo, jak opisywać dane natywne:
- Rodzina layoutów:
ValueLayout,SequenceLayout,StructLayout,UnionLayout - Nazwy pól nadaje się za pomocą
withName, a dostęp do nich uzyskuje przezVarHandlei elementy ścieżki - W celu prawidłowego wyrównania należy jawnie dodać
paddingLayout - Można łączyć zagnieżdżone layouty i wycinać fragmenty za pomocą
asSlice
To kończy kurs Foreign Function and Memory API.
Często zadawane pytania
Czy lekcja „Układy pamięci i struktury” jest bezpłatna?
Tak — pełny tekst „Układy pamięci i struktury” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Układy pamięci i struktury”?
Opisywanie układów pamięci natywnej Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Java Academy?
Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Układy pamięci i struktury”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?
Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Dlaczego FFM zamiast JNI
- MemorySegment i Arena
- Uchwyty downcall
- Układy pamięci i struktury