Ich habe ein Gradle-Plug-In erstellt, wie der Titel sagt. Wir bewerben uns derzeit für das Gradle-Repository. Klicken Sie hier für den Quellcode
jnr-ffi Plugin
Dieses Plug-In erleichtert die Verwendung der in der Entwicklung befindlichen Funktionen (die in Java 13 implementiert werden sollen) in Project Panama.
Insbesondere soll JEP 191: Foreign Function Interface komfortabler gestaltet werden.
JNR-bezogene Artikel sind in dieser Qiita zusammengefasst. Bitte zögern Sie nicht, uns zu kontaktieren.
Version 13 oder höher für System-JDK und Projekt-JDK?
Das zertifizierte JDK lautet Project Panama Early-Access Builds. nur.
Eine Warnmeldung wird ausgegeben, wenn die JDK-Version 12 oder weniger ist, und eine Fehlermeldung wird ausgegeben, wenn Jextract nicht im System-JDK vorhanden ist.
jextract
jextract ist ein Tool, das die entsprechende Java-Schnittstelle aus .h-Dateien wie der C-Sprache generiert.
Es ist an Early-Access-Version von JDK und an Service Loader angehängt. Es kann auch programmgesteuert mit api / java / util / ServiceLoader.html aufgerufen werden.
Dieses Plug-In definiert eine Aufgabe namens Jextract.
Die Aufgabe jextract verwendet jextract, um eine JAR-Datei (entsprechende Schnittstelle) aus der .h-Datei im angegebenen Ordner zu generieren.
(Es sucht auch nach verschachtelten Dateien und ordnet das Verzeichnis dem Paket zu, um ein JAR zu generieren.)
Optionen für die Jextract-Aufgabe können in build.gradle wie folgt angegeben werden:
build.gradle
jextract{
// .h Der Pfad des Verzeichnisses, das die Datei enthält
//Der Anfangswert ist"src/main/resources/"
sourceRoot = "head/"
//Pfad des Verzeichnisses zum Ablegen des generierten JAR
//Der Anfangswert ist"libs/"
outPath = "jar"
//Der Stammname des Pakets, zu dem die zu generierende Schnittstelle gehört
// <packageRoot>.<Verzeichnisname>.<Verzeichnisname>Ist wie benannt
//Der Anfangswert ist""
packageRoot = "pkg"
//Gibt an, ob der Paketname das Verzeichnis sourceRoot enthält
//Wenn false festgelegt ist, befindet es sich direkt unter SourceRoot..h Das Dateipaket wird zu packageRoot
//Der Anfangswert ist falsch
includeRoot = false
}
Rufen Sie jextract mit ServiceLoader auf. Wenn Sie versuchen, com.sun.tools.jextract.Main $ JextractToolProvider direkt aufzurufen, wird übrigens ein Kompilierungsfehler angezeigt. (Liegt es an resources / Message.properties?)
Schreiben wir nun den Java-Code.
Test.java
public class Test{
public static void main(String[] args){
//Rufen Sie die Liste der ToolProvider-Implementierungen mit ServiceLoader ab.
//Diejenigen im JDK-Bin, wie z. B. jshell und jextract, werden zurückgegeben.
//Der Werkzeugname von jextract lautet"jextract"Verwenden Sie also die passende.
ServiceLoader<ToolProvider> providers = load(ToolProvider.class);
ToolProvider provider = null;
for (ToolProvider tool : providers) {
if (tool.name().equals("jextract")) provider = tool;
}
if(provider == null) System.out.println("Error:Jextrakt existiert nicht.");
//Übergeben Sie die Befehlszeilenargumente beim Aufrufen von jextract an das letzte Argumentarray.
//Trennen Sie Elemente, anstatt sie durch Leerzeichen zu trennen.
provider.run(System.out, System.err, String[]{"src/main/resources/test.h"});
}
}
test.h
int hoge(void);
Wenn Sie test.h in src / main / resources / erstellen und Test.main ausführen, wird eine Datei mit dem Namen test.h.jar direkt unter dem Projekt erstellt.
Außerdem werden die diesmal verwendeten Optionen extrahiert.
Möglichkeit | Streit | Erläuterung |
---|---|---|
-t | Paketnamen | Die generierte Schnittstelle gehört zum Paket |
-o | Dateiname(Einschließlich des Pfades) | Dateiname(Pfad)Die generierte JAR-Datei wird in abgelegt |
Dateiname(Einschließlich des Pfades) | Ich möchte konvertieren.Dateiname der h-Datei(Pfad) Mehrfachauswahl ist möglich, wird jedoch immer als dasselbe Paket generiert |
Zum Beispiel
jextract -t pkg -o out.jar test.h
Wenn Sie den Befehl ausführen, oder
Test.java
public class Test{
public static void main(String[] args){
ServiceLoader<ToolProvider> providers = load(ToolProvider.class);
ToolProvider provider = null;
for (ToolProvider tool : providers) {
if (tool.name().equals("jextract")) provider = tool;
}
provider.run(System.out, System.err, String[]{"-o", "out.jar", "-t", "pkg", "test.h"});
}
}
Als ich das Programm lief
test.h
int hoge(void);
Wenn es eine Datei mit dem Namen out.jar gibt, wird eine Datei mit dem Namen out.jar generiert.
out.jar
|-META-INF
| \jextract.properties
\pkg
\test.class
Die interne Struktur von out.jar ist wie folgt, und Sie können sehen, dass ein Paketverzeichnis namens pkg generiert wird.
Wenn Sie Test.class mit jad rückwärts kompilieren, sehen Sie, dass es so aussieht:
Test.jad
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
package pkg;
public interface test
{
public abstract int hoge();
}
Die .h-Datei ist fest auf die Schnittstelle übertragen.
Als ich es zu einem Plug-In gemacht habe, hat ServiceLoader kein Jextract gefunden. Nachdem ich das System-JDK auf 13 geändert habe, habe ich den Aufruf ein wenig geändert.
public class Test{
public static void main(String[] args){
//Verwenden Sie den Systemklassenlader
ServiceLoader<ToolProvider> providers = load(ToolProvider.class, ClassLoader.getSystemClassLoader());
ToolProvider provider = null;
for (ToolProvider tool : providers) {
if (tool.name().equals("jextract")) provider = tool;
}
provider.run(System.out, System.err, String[]{"-o", "out.jar", "-t", "pkg", "test.h"});
}
}
Ich habe auf diesen Artikel verwiesen.
Recommended Posts