- 関数型インタフェース:
- これは関数型インタフェースなので、ラムダ式またはメソッド参照の代入先として使用できます。
SymbolLookup
は、JavaプラットフォームのプレビューAPIです。
シンボル・ルックアップは、特定のライブラリ (またはライブラリ)に対して作成されます。 その後、lookup(String)
メソッドはシンボルの名前を取得し、そのライブラリ内のシンボルのアドレスを返します。
シンボルのアドレスは、長さゼロの「メモリー・セグメント」PREVIEWとしてモデル化されます。 セグメントは次の様々な方法で使用できます:
Linker
PREVIEWに渡してダウンコール・メソッド・ハンドルを作成でき、これを使用してセグメント・ベース・アドレスで外部関数をコールできます。- 既存の「ダウンコール・メソッド・ハンドル」PREVIEWに、基礎となる外部関数の引数として渡すことができます。
- 別のメモリー・セグメント内の「保管済み」PREVIEWにできます。
- グローバル変数(最初に
resizing
PREVIEWセグメントが必要になる場合があります)に関連付けられたメモリーを参照解除するために使用できます。
シンボル・ルックアップの取得
ファクトリ・メソッドlibraryLookup(String, MemorySession)
およびlibraryLookup(Path, MemorySession)
は、オペレーティング・システムで認識されているライブラリのシンボル・ルックアップを作成します。 ライブラリは、その名前またはパスで指定されます。 ライブラリがまだロードされていない場合はロードされます。 「ライブラリ・ルックアップ」と呼ばれるシンボル・ルックアップは、「メモリー・セッション」PREVIEWに関連付けられています。セッションがclosedPREVIEWの場合、ライブラリはアンロードされます:
try (MemorySession session = MemorySession.openConfined()) {
SymbolLookup libGL = SymbolLookup.libraryLookup("libGL.so"); // libGL.so loaded here
MemorySegment glGetString = libGL.lookup("glGetString").orElseThrow();
...
} // libGL.so unloaded here
以前にSystem.load(String)
またはSystem.loadLibrary(String)
によってJNI、i.eを介してライブラリがロードされていた場合、ライブラリは特定のクラス・ローダーにも関連付けられていました。 ファクトリ・メソッドloaderLookup()
は、コール元クラス・ローダーに関連付けられたすべてのライブラリのシンボル・ルックアップを作成します:
System.loadLibrary("GL"); // libGL.so loaded here
...
SymbolLookup libGL = SymbolLookup.loaderLookup();
MemorySegment glGetString = libGL.lookup("glGetString").orElseThrow();
ローダー・ルックアップでは、System.load(String)
またはSystem.loadLibrary(String)
によって以前にJNI、i.eを介してロードされたライブラリ内の記号のみが公開されることに注意してください。 ローダー・ルックアップでは、ライブラリ・ルックアップの作成中にロードされたライブラリ内のシンボルは公開されません:
libraryLookup("libGL.so", session).lookup("glGetString").isPresent(); // true
loaderLookup().lookup("glGetString").isPresent(); // false
L
のライブラリ・ルックアップでは、L
が以前にJNI (クラス・ローダーとの関連付けはライブラリ・ルックアップにとって重要ではありません)を介してロードされている場合でも、L
のシンボルが公開されることにも注意してください:
System.loadLibrary("GL"); // libGL.so loaded here
libraryLookup("libGL.so", session).lookup("glGetString").isPresent(); // true
最後に、各Linker
PREVIEWは、そのLinker
PREVIEWでサポートされるOSとプロセッサの組合せで一般的に使用されるライブラリのシンボル・ルックアップを提供します。 このシンボル・ルックアップは「デフォルト・ルックアップ」と呼ばれ、クライアントが既知のシンボルのアドレスをすばやく検索するのに役立ちます。 たとえば、Linux/x64のLinker
PREVIEWは、デフォルト・ルックアップを介してlibc
のシンボルを公開することを選択できます:
Linker nativeLinker = Linker.nativeLinker();
SymbolLookup stdlib = nativeLinker.defaultLookup();
MemorySegment malloc = stdlib.lookup("malloc").orElseThrow();
-
メソッドのサマリー
修飾子と型メソッド説明static SymbolLookupPREVIEW
libraryLookup
(String name, MemorySessionPREVIEW session) 指定された名前 (まだロードされていない場合)のライブラリをロードし、そのライブラリ内のシンボルのシンボル・ルックアップを作成します。static SymbolLookupPREVIEW
libraryLookup
(Path path, MemorySessionPREVIEW session) 指定されたパス (まだロードされていない場合)からライブラリをロードし、そのライブラリ内のシンボルのシンボル・ルックアップを作成します。static SymbolLookupPREVIEW
呼び出し元クラス・ローダーに関連付けられたライブラリ内のシンボルのシンボル・ルックアップを返します。指定された名前のシンボルのアドレスを返します。
-
メソッドの詳細
-
lookup
Optional<MemorySegmentPREVIEW> lookup(String name) 指定された名前のシンボルのアドレスを返します。- パラメータ:
name
- シンボル名。- 戻り値:
- 見つかった場合、ベース・アドレスがシンボルのアドレスを示す長さがゼロのメモリー・セグメント。
-
loaderLookup
static SymbolLookupPREVIEW loaderLookup()呼び出し元クラス・ローダーに関連付けられたライブラリ内のシンボルのシンボル・ルックアップを返します。ライブラリは、
CL
で定義されるクラスのコードからSystem.load(String)
またはSystem.loadLibrary(String)
を呼び出してライブラリをロードすると、クラス・ローダーCL
に関連付けられます。 このコードによってSystem.load(String)
またはSystem.loadLibrary(String)
がさらに起動される場合、より多くのライブラリがロードされ、CL
に関連付けられます。 このメソッドによって返されるシンボル・ルックアップは常に最新です: このメソッドが返された後にロードされた場合でも、関連するクラス・ローダーに関連付けられたすべてのライブラリが反映されます。クラス・ローダーに関連付けられたライブラリは、クラス・ローダーがunreachableになるとアンロードされます。 このメソッドによって返されるシンボル・ルックアップは、non-closeablePREVIEWの共有メモリー・セッションによって、呼び出し元クラス・ローダーにアクセス可能な状態に保たれます。 したがって、コール元クラス・ローダーに関連付けられたライブラリは、そのクラス・ローダーに対するローダー・ルックアップがアクセス可能なかぎり、(およびそれらのシンボルが使用可能)をロードしたままになります。
スタック(例、JNIアタッチ・スレッドから直接コールされる場合)にコール元フレームがないコンテキストからこのメソッドがコールされる場合、コール元クラス・ローダーはデフォルトで「システム・クラス・ローダー」に設定されます。
- 戻り値:
- 呼び出し元クラス・ローダーに関連付けられたライブラリ内のシンボルのシンボル・ルックアップ。
- 関連項目:
-
libraryLookup
static SymbolLookupPREVIEW libraryLookup(String name, MemorySessionPREVIEW session) 指定された名前 (まだロードされていない場合)のライブラリをロードし、そのライブラリ内のシンボルのシンボル・ルックアップを作成します。 指定されたメモリー・セッションがclosedPREVIEWの場合は、ライブラリがアンロードされます(まだほかのライブラリ・ルックアップで使用されていない場合)。- 実装上のノート:
- ライブラリ名の解決プロセスはOS固有です。 たとえば、POSIX準拠のOSでは、ライブラリ名はそのOSの
dlopen
関数の指定に従って解決されます。 Windowsでは、ライブラリ名はLoadLibrary
関数の指定に従って解決されます。このメソッドは「制限付き」です。 制限されたメソッドは安全ではなく、誤って使用するとJVMがクラッシュしたり、悪化したりするとメモリーが破損する可能性があります。 したがって、クライアントは制限付きメソッドに応じて屈折し、可能な場合は安全でサポートされている機能を使用する必要があります。
- パラメータ:
name
- シンボルを検索するライブラリの名前。session
- ライブラリ・ライフ・サイクルを管理するメモリー・セッション。- 戻り値:
- 指定された名前を持つライブラリ内のシンボルを検索するのに適した新しいシンボル・ルックアップ。
- 例外:
IllegalArgumentException
-name
が有効なライブラリを識別しない場合。IllegalCallerException
- このメソッドへのアクセスがモジュールM
から発生し、コマンドライン・オプション--enable-native-access
がない場合、またはモジュール名M
が名前なしモジュールの場合はALL-UNNAMED
は説明しません。
-
libraryLookup
static SymbolLookupPREVIEW libraryLookup(Path path, MemorySessionPREVIEW session) 指定されたパス (まだロードされていない場合)からライブラリをロードし、そのライブラリ内のシンボルのシンボル・ルックアップを作成します。 指定されたメモリー・セッションがclosedPREVIEWの場合は、ライブラリがアンロードされます(まだほかのライブラリ・ルックアップで使用されていない場合)。このメソッドは「制限付き」です。 制限されたメソッドは安全ではなく、誤って使用するとJVMがクラッシュしたり、悪化したりするとメモリーが破損する可能性があります。 したがって、クライアントは制限付きメソッドに応じて屈折し、可能な場合は安全でサポートされている機能を使用する必要があります。
- 実装上のノート:
- Linuxでは、このファクトリ・メソッドによって提供される機能および返されるシンボル・ルックアップは、
dlopen
、dlsym
およびdlclose
関数を使用して実装されます。 - パラメータ:
path
- シンボルを検索するライブラリのパス。session
- ライブラリ・ライフ・サイクルを管理するメモリー・セッション。- 戻り値:
- 指定されたパスを持つライブラリ内のシンボルを見つけるのに適した新しいシンボル・ルックアップ。
- 例外:
IllegalArgumentException
-path
が有効なライブラリを指していない場合。IllegalCallerException
- このメソッドへのアクセスがモジュールM
から発生し、コマンドライン・オプション--enable-native-access
がない場合、またはモジュール名M
が名前なしモジュールの場合はALL-UNNAMED
は説明しません。
-
SymbolLookup
を使用できます。