Heim  >  Artikel  >  Java  >  Javas JNA-Typzuordnung, Liebe zum Detail und zur Verwendung

Javas JNA-Typzuordnung, Liebe zum Detail und zur Verwendung

王林
王林nach vorne
2023-04-18 17:07:031254Durchsuche

String

Die erste ist, dass die Zuordnung von String in JAVA tatsächlich zwei nativen Typen entspricht: const char* und const wchar_t*. Standardmäßig wird String in char* konvertiert.

char ist ein ANSI-Datentyp und wchar_t ist ein Unicode-Zeichendatentyp, auch Breitzeichen genannt.

Wenn die Unicode-Zeichen von JAVA in char-Arrays konvertiert werden sollen, müssen einige Codierungsvorgänge ausgeführt werden. Wenn jna.encoding festgelegt ist, wird die festgelegte Codierungsmethode zur Codierung verwendet. Standardmäßig ist die Kodierungsmethode „UTF8“.

Wenn es sich um WString handelt, können Unicode-Werte ohne Kodierung direkt nach WString kopiert werden.

Schauen wir uns zunächst ein einfaches Beispiel an:

char* returnStringArgument(char *arg) {
  return arg;
}

wchar_t* returnWStringArgument(wchar_t *arg) {
  return arg;
}

Der obige native Code kann abgebildet werden auf:

String returnStringArgument(String s);
WString returnWStringArgument(WString s);

Schauen wir uns noch einmal ein anderes Beispiel an, wenn die Definition der nativen Methode so lautet:

int getString(char* buffer, int bufsize);

int getUnicodeString(wchar_t* buffer, int bufsize);

Wir haben definiert zwei Methoden, method Die Parameter sind char* bzw. wchar_t*.

Schauen wir uns als Nächstes an, wie die Methodenzuordnung in JAVA definiert wird:

// Mapping A:
int getString(byte[] buf, int bufsize);
// Mapping B:
int getUnicodeString(char[] buf, int bufsize);

Das Folgende ist die spezifische Verwendung:

byte[] buf = new byte[256];
int len = getString(buf, buf.length);
String normalCString = Native.toString(buf);
String embeddedNULs = new String(buf, 0, len);

Einige Schüler fragen sich vielleicht, warum String in JAVA in char* konvertiert werden kann Hier Byte verwenden? Was ist mit Arrays?

Das liegt daran, dass die getString-Methode den Inhalt des eingehenden char-Arrays ändern muss, aber da String unveränderlich ist, kann String hier nicht direkt verwendet werden. Wir müssen ein Byte-Array verwenden.

Dann verwenden wir Native.toString(byte[]), um das Byte-Array in einen JAVA-String umzuwandeln.

Sehen wir uns einen anderen Rückgabewert an:

// Example A: Returns a C string directly
const char* getString();
// Example B: Returns a wide character C string directly
const wchar_t* getString();

Wenn die native Methode einen String direkt zurückgibt, können wir im Allgemeinen String für die Zuordnung verwenden:

// Mapping A
String getString();
// Mapping B
WString getString();

Wenn der native Code Speicherplatz für String zuweist, verwenden wir besser den Zeiger in Als Rückgabewert wird JNA verwendet, damit wir den belegten Speicherplatz irgendwann in der Zukunft freigeben können, wie unten gezeigt:

Pointer getString();

Puffer, Speicher, Arrays und Zeiger

Wann müssen wir Puffer und Speicher verwenden?

Wenn ein Array mit Basisdaten als Parameter an eine Funktion übergeben wird, können Sie im Allgemeinen stattdessen direkt ein Array mit Basisklassen in JAVA verwenden. Wenn die native Methode jedoch nach der Rückkehr der Methode weiterhin auf das Array zugreifen muss (Speichern des Zeigers auf das Array), ist es in diesem Fall nicht angemessen, das Array der Basisklasse zu verwenden. In diesem Fall müssen wir ByteBuffers oder verwenden Erinnerung .

Wir wissen, dass Arrays in JAVA Längen haben, aber bei nativen Methoden ist das zurückgegebene Array tatsächlich ein Zeiger auf das Array. Wir kennen die Länge des zurückgegebenen Arrays nicht. Wenn die native Methode also ein Array zurückgibt, gilt Folgendes: Es ist ungeeignet, Arrays für die Zuordnung im JAVA-Code zu verwenden. In diesem Fall muss Pointer verwendet werden. Schauen wir uns zunächst das Beispiel von Pointer an:

void* returnPointerArgument(void *arg) {
  return arg;
}

void* returnPointerArrayElement(void* args[], int which) {
  return args[which];
}

Das nächste ist die JAVA-Zuordnung:

Pointer returnPointerArgument(Pointer p);
Pointer returnPointerArrayElement(Pointer[] args, int which);

Basic Pointer: Sie können auch einen typisierten Zeiger anpassen, d

entspricht Puffer Im Allgemeinen stellt JAVA NIO viele Arten von Puffern bereit, z. B. ByteBuffer, ShortBuffer, IntBuffer, LongBuffer, FloatBuffer und DoubleBuffer usw. Hier nehmen wir ByteBuffer als Beispiel, um die spezifische Verwendung zu sehen.

Schauen Sie sich zunächst den nativen Code an:

public static class TestPointerType extends PointerType {
            public TestPointerType() { }
            public TestPointerType(Pointer p) { super(p); }
        }
TestPointerType returnPointerArrayElement(TestPointerType[] args, int which);

Der Puffer wird hier offensichtlich verwendet, daher ist die Verwendung eines Arrays unangemessen Hier können Sie ByteBuffer verwenden:

char* returnStringArrayElement(char* args[], int which) {
  return args[which];
}
wchar_t* returnWideStringArrayElement(wchar_t* args[], int which) {
  return args[which];
}

Dann schauen Sie sich an, wie man es verwendet:

String returnStringArrayElement(String[] args, int which);

WString returnWideStringArrayElement(WString[] args, int which);

Variable Parameter

Für native und JAVA selbst unterstützen beide variable Parameter. Lassen Sie uns ein Beispiel in der nativen Methode geben :

Die entsprechende JAVA-Methodenzuordnung von

int32_t fillInt8Buffer(int8_t *buf, int len, char value) {
  int i;

  for (i=0;i < len;i++) {
    buf[i] = value;
  }
  return len;
}

lautet wie folgt:

int fillInt8Buffer(ByteBuffer buf, int len, byte value);

Der entsprechende Aufrufcode lautet wie folgt:

TestLibrary lib = Native.load("testlib", TestLibrary.class);

        ByteBuffer buf  = ByteBuffer.allocate(1024).order(ByteOrder.nativeOrder());
        final byte MAGIC = (byte)0xED;
        lib.fillInt8Buffer(buf, 1024, MAGIC);
        for (int i=0;i < buf.capacity();i++) {
            assertEquals("Bad value at index " + i, MAGIC, buf.get(i));
        }

Das obige ist der detaillierte Inhalt vonJavas JNA-Typzuordnung, Liebe zum Detail und zur Verwendung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen