J2ObjC unterstützt die Einbettung von Objective-C in native Java-Methoden, ähnlich wie bei der
JSNI von GWT unterstützt
JavaScript-Einbettung. Der Hauptunterschied zwischen J2ObjC-Einbettung und GWT besteht darin, dass J2ObjC
/*-[
und ]-*/
, um den Objective-C-Code abzugrenzen. Diese Einrichtung wird als OCNI (Objective-C) bezeichnet.
Native Interfaces), um sich von der JSNI von GWT zu unterscheiden.
Hier ein Beispiel aus der Version von java.lang.System
der JRE-Emulationsbibliothek:
public static native long currentTimeMillis() /*-[
// Use NSDate
return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
]-*/;
J2ObjC kopiert den Kommentar ohne die Trennzeichen, um den Methodentext zu erstellen:
+ (long long int)currentTimeMillis {
// Use NSDate
return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
}
Native Importe
J2ObjC scannt den zu übersetzenden Java-Code, um #import-Anweisungen für seine Abhängigkeiten hinzuzufügen, und als Import des Grundlagen-Frameworks. Alle Importe, die nur mit nativem Code benötigt werden, müssen jedoch separat hinzugefügt werden. Um Importe hinzuzufügen, fügen Sie in der Java-Quelldatei über der ersten Klasse einen OCNI-Abschnitt ein und die Importe dort angeben. Beispiel:
package my.project;
/*-[
#import "java/lang/NullPointerException.h"
]-*/
public class Test {
native void test() /*-[
@throw [[JavaLangNullPointerException alloc] init];
]-*/;
}
Der Import ist im obigen Beispiel erforderlich, da der einzige Ort, auf den dieser Typ verwiesen wird, sich in nativen Code.
Native Blöcke
Innerhalb eines Klassentextes sucht J2ObjC nach OCNI-Blöcken. Diese Blöcke werden der übersetzte Datei an derselben Position relativ zu den übersetzten Kursteilnehmern angezeigt werden. Beispiel:
/*-[
static void log(NSString *msg) {
NSLog(@"%@", msg);
}
]-*/;
Diese C-Funktion kann über jede native Methode aufgerufen werden, die nach diesem OCNI-Block deklariert wird.
Mit einer speziellen Variante dieses OCNI-Blocks wird stattdessen Code in den generierten Header eingefügt.
der M-Datei: /*-HEADER[...]
Java-Methoden aus nativem Code aufrufen
public native void bar(JSNIExample x, String s) /*-[
// Call instance method instanceFoo() on this
[self instanceFooWithNSString:s];
// Call instance method instanceFoo() on x
[x instanceFooWithNSString:s];
// Call static method staticFoo()
JSNIExample_staticFooWithNSString_(s);
]-*/;
Über nativen Code auf Felder zugreifen
Um ein Instanzfeld zu lesen, verwenden Sie entweder myInstanceField_
oder
self->myInstanceField_
. Das nachgestellte Suffix verhindert einen Konflikt mit Methoden
mit demselben Namen.
Felder mit reservierten Namen haben zwei Unterstriche. Beispiel: ein Feld namens „id“ ist in Java legal, aber nicht in Objective-C. Bei der Übersetzung erhält dieses Feld den Namen „id__“. Prüfen Sie daher bitte die generierten Dateien, gibt es „no-so-field“ Compiler-Fehler.
Verwenden Sie JSNIExample_set_myInstanceField(string)
, um in das Feld einer Objektinstanz zu schreiben
Statisches Feld lesen: JSNIExample_get_myStaticField()
Statisches Feld schreiben: JSNIExample_set_myStaticField(value)
J2ObjC und GWT
Unterschiedliche Trennzeichen wurden gewählt, sodass GWT JSNI-Kommentare in der nächsten J2ObjC-Version ignoriert (zuvor wurden dieselben Trennzeichen als GWT verwendet). Das bedeutet, dass eine einzelne Java-Quelle native Methoden mit Objective-C-, GWT- und Android (über JNI)-Implementierungen haben:
static native void log(String text) /*-{ // left-brace for JavaScript
console.log(text);
}-*/ /*-[ // left-bracket for Objective-C
NSLog(@"%@", text);
]-*/;
J2ObjC und Android
Nativen Methodenimplementierungen für J2ObjC und Android funktionieren einfach, da native Methoden von Android in einer separaten JNI C- oder C++-Datei implementiert. OCNI-Kommentare in Java-Klassen werden entfernt, wenn die mit Javac für Android oder eine andere Java-Plattform kompiliert wurden.