インタフェースSymbolLookup

関数型インタフェース:
これは関数型インタフェースなので、ラ ダ式またはメソッド参照の代入先として使用できます。

@FunctionalInterface public interface SymbolLookup
「シンボル・ルックアップ」は、1つ以上のライブラリ内のシンボルのアドレスを取得します。 シンボルは、関数やグローバル変数などの名前付きエンティティです。

シンボル・ルックアップは、特定のライブラリ (またはライブラリ)に対して作成されます。 その後、find(String)メソッドはシンボルの名前を取得し、そのライブラリ内のシンボルのアドレスを返します。

シンボルのアドレスは、長さゼロの「メモリー・セグメント」としてモデル化されます。 セグメントは次の様々な方法で使用できます:

  • Linkerに渡してダウンコール・メソッド・ハンドルを作成でき、これを使用してセグメントのアドレスで外部ファンクションをコールできます。
  • これは、基礎となる外部関数への引数として、既存の「ダウンコール・メソッド・ハンドル」RESTRICTEDに渡すことができます。
  • 別のメモリー・セグメント内で「保管済み」にできます。
  • グローバル変数(これには、最初にセグメントを「サイズ変更」RESTRICTEDする必要があります)をバッキングするメモリーのリージョンにアクセスするために使用できます。

シンボル・ルックアップの取得

ファクトリ・メソッドlibraryLookup(String, Arena)RESTRICTEDおよびlibraryLookup(Path, Arena)RESTRICTEDは、オペレーティング・システ で認識されるライブラリのシンボル・ルックアップを作成します。 ライブラリは、その名前またはパスで指定されます。 ライブラリがま ロードされていない 合はロードされます。 シンボル・ルックアップ(「ライブラリ・ルックアップ」と呼ばれ、その存続期間は「アリーナ」によって制御されます)。 たとえば、指定されたアリーナが限定されたアリーナである 合、限定されたアリーナがclosedのときに、シンボル・ルックアップに関連付けられたライブラリがアンロードされます。
 try (Arena arena = Arena.ofConfined()) {
     SymbolLookup libGL = SymbolLookup.libraryLookup("libGL.so", arena); // libGL.so loaded here
     MemorySegment glGetString = libGL.findOrThrow("glGetString");
     ...
 } //  libGL.so unloaded here

ライブラリが以前にJNI (System.load(String)RESTRICTEDまたはSystem.loadLibrary(String)RESTRICTED)を介してロードされていた 合、そのライブラリは特定のクラス・ローダーにも関連付けられました。 ファクトリ・メソッドloaderLookup()は、コール元のクラス・ローダーに関連付けられたすべてのライブラリのシンボル・ルックアップを作成します:

System.loadLibrary("GL"); // libGL.so loaded here
...
SymbolLookup libGL = SymbolLookup.loaderLookup();
MemorySegment glGetString = libGL.findOrThrow("glGetString");
このシンボル・ルックアップは「ローダー・ルックアップ」と呼ばれ、クラス・ローダーに関連付けられたライブラリに関して動的です。 その後、他のライブラリがJNIを介してロードされ、クラス・ローダーに関連付けられている 合、ローダー・ルック・アッ・ルックアッププではそのシンボルが自動的に公開されます。

ローダー・ルックアップでは、以前にJNIを介してロードされたライブラリ(つまり、System.load(String)RESTRICTEDまたはSystem.loadLibrary(String)RESTRICTEDによって)のシンボルのみが公開されることに注意してく さい。 ローダー・ルックアップでは、ライブラリ・ルックアップの作成中にロードされたライブラリ内のシンボルは公開されません:

 libraryLookup("libGL.so", arena).find("glGetString").isPresent(); // true
 loaderLookup().find("glGetString").isPresent(); // false
ライブラリLのライブラリ・ルックアップでは、Lが以前にJNI (クラス・ローダーとの関連付けはライブラリ・ルックアップにとって重要ではありません)を介してロードされている 合でも、Lのシンボルが公開されることにも注意してく さい:
 System.loadLibrary("GL"); // libGL.so loaded here
 libraryLookup("libGL.so", arena).find("glGetString").isPresent(); // true

最後に、各Linkerは、そのLinkerでサポートされているOSとプロセッサの組合せで一般的に使用されるライブラリのシンボル・ルックアップを提供します。 このシンボル・ルックアップは「デフォルト・ルックアップ」と呼ばれ、クライアントが既知のシンボルのアドレスをすばやく検索するのに役立ちます。 たとえば、Linux/x64のLinkerは、デフォルトのルックアップを介してlibcのシンボルを公開することを選択できます。

 Linker nativeLinker = Linker.nativeLinker();
 SymbolLookup stdlib = nativeLinker.defaultLookup();
 MemorySegment malloc = stdlib.findOrThrow("malloc");

導入されたバージョン:
22
  • メソッドのサマリー

    修飾子と型
    メソッド
    説明
    find(String name)
    指定された名前のシンボルのアドレスを返します。
    指定された名前を持つシンボルのアドレスを返すか、例外をスローします。
    libraryLookup(String name, Arena arena)
    Restricted.
    指定された名前 (ま ロードされていない 合)のライブラリをロードし、そのライブラリ内のシンボルのシンボル・ルックアップを作成します。
    libraryLookup(Path path, Arena arena)
    Restricted.
    指定されたパス (ま ロードされていない 合)からライブラリをロードし、そのライブラリ内のシンボルのシンボル・ルックアップを作成します。
    呼び出し元クラス・ローダーに関連付けられたライブラリ内のシンボルのシンボル・ルックアップを返します。
    default SymbolLookup
    シンボルが見つかった 合は、このルックアップでシンボルを検索した結果を返す合成シンボル・ルックアップを返します。それ以外の 合は、ほかの検索でシンボルを検索した結果を返します。
  • メソッドの詳細

    • find

      指定された名前のシンボルのアドレスを返します。
      パラメータ:
      name - シンボル名
      戻り値:
      アドレスがシンボルのアドレスを示す長さがゼロのメモリー・セグメント(見つかった 合)
      関連 目:
    • findOrThrow

      default MemorySegment findOrThrow(String name)
      指定された名前を持つシンボルのアドレスを返すか、例外をスローします。

      これは次のコードと同等ですが、より効率的です: 宛先:

         String name = ...
         MemorySegment address = lookup.find(name)
             .orElseThrow(() -> new NoSuchElementException("Symbol not found: " + name));
      

      パラメータ:
      name - シンボル名
      戻り値:
      アドレスがシンボルのアドレスを示す長さゼロのメモリー・セグメント
      スロー:
      NoSuchElementException - 指定された名前のシンボル・アドレスが見つからない 合
      導入されたバージョン:
      23
      関連 目:
    • or

      default SymbolLookup or(SymbolLookup other)
      シンボルが見つかった 合は、このルックアップでシンボルを検索した結果を返す合成シンボル・ルックアップを返します。それ以外の 合は、ほかの検索でシンボルを検索した結果を返します。
      APIのノート:
      このメソッドは、複数のシンボル・ルックアップをまとめて連鎖するために使用できます。たとえば、シンボルを複数のライブラリから 番に取得できるようにするためです:
       var lookup = SymbolLookup.libraryLookup("foo", arena)
               .or(SymbolLookup.libraryLookup("bar", arena))
               .or(SymbolLookup.loaderLookup());
      
      前述のコードは、最初に"foo"ライブラリ内のシンボルを検索するシンボル・ルックアップを作成します。 "foo"に記号が見つからない 合は、"バール"が検索されます。 最後に、シンボルが"foo"にも"バール"にもない 合、「ローダー・ルックアップ」が使用されます。
      パラメータ:
      other - この検索で見つからないシンボルの検索に使用するシンボル・ルックアップ
      戻り値:
      シンボルが見つかった 合、このルックアップでシンボルを検索した結果を返す合成シンボル・ルックアップ。それ以外の 合は、ほかのルックアップでシンボルを検索した結果を返します
    • loaderLookup

      static SymbolLookup loaderLookup()
      呼び出し元クラス・ローダーに関連付けられたライブラリ内のシンボルのシンボル・ルックアップを返します。

      ライブラリは、CLで定義されたクラスのコードからSystem.load(String)RESTRICTEDまたはSystem.loadLibrary(String)RESTRICTEDを起動してライブラリをロードするときに、クラス・ローダーCLに関連付けられます。 このコードによってSystem.load(String)RESTRICTEDまたはSystem.loadLibrary(String)RESTRICTEDがさらに起動される 合、さらに多くのライブラリがロードされ、CLに関連付けられます。 このメソッドによって返されるシンボル・ルックアップは常に最新です: このメソッドが返された後にロードされた 合でも、関連するクラス・ローダーに関連付けられたすべてのライブラリが反 されます。

      クラス・ローダーに関連付けられたライブラリは、クラス・ローダーがunreachableになるとアンロードされます。 このメソッドによって返されるシンボル・ルックアップは、呼出し側のクラス・ローダーが到達可能な状態を維持する自動scopeに関連付けられます。 そのため、コール元のクラス・ローダーに関連付けられたライブラリは、そのクラス・ローダーまたはそれによって取得されたセグメントのいずれかのローダー・ルックアップがアクセス可能なかぎり、ロードされた(およびそれらのシンボルが使用可能)が保持されます。

      スタック(例、JNIアタッチ・スレッドから直接コールされる 合)にコール元フレー がないコンテキストからこのメソッドがコールされる 合、コール元クラス・ローダーはデフォルトで「システ ・クラス・ローダー」に設定されます。

      戻り値:
      呼び出し元のクラス・ローダーに関連付けられたライブラリ内のシンボルのシンボル・ルックアップ
      関連 目:
    • libraryLookup

      static SymbolLookup libraryLookup(String name, Arena arena)
      libraryLookupは、Javaプラットフォー の制限付きメソッドです。
      プログラ は、制限付きメソッドへのアクセスが有効になっている 合にのみlibraryLookupを使用できます。
      制限されたメソッドは安全ではありません。不適切に使用した 合、JVMがクラッシュまたはメモリーが 損する 合があります。
      指定された名前 (ま ロードされていない 合)のライブラリをロードし、そのライブラリ内のシンボルのシンボル・ルックアップを作成します。 返されるライブラリ・ルックアップの存続期間は、指定されたアリーナによって制御されます。 たとえば、提供されたアリーナが限定されたアリーナである 合、提供された限定されたアリーナがclosedの 合、返されたルックアップに関連付けられたライブラリはアンロードされます。
      実装上のノート:
      ライブラリ名の解決プロセスはOS固有です。 たとえば、POSIX準 のOSでは、ライブラリ名はそのOSのdlopen関数の指定に従って解決されます。 Windowsでは、ライブラリ名はLoadLibrary関数の指定に従って解決されます。
      パラメータ:
      name - シンボルを検索するライブラリの名前
      arena - 返されたルックアップから取得されたシンボルに関連付けられたアリーナ
      戻り値:
      指定された名前のシンボルをライブラリ内で検索するのに適した新しいシンボル・ルックアップ
      スロー:
      IllegalStateException - arena.scope().isAlive() == falseの 合
      WrongThreadException - arenaが限定アリーナで、このメソッドがアリーナの所有者スレッド以外のスレッドTからコールされる 合
      IllegalArgumentException - nameが有効なライブラリを識別しない 合
      IllegalCallerException - 呼出し元が、ネイティブ・アクセスが有効になっていないモジュール内にある 合
    • libraryLookup

      static SymbolLookup libraryLookup(Path path, Arena arena)
      libraryLookupは、Javaプラットフォー の制限付きメソッドです。
      プログラ は、制限付きメソッドへのアクセスが有効になっている 合にのみlibraryLookupを使用できます。
      制限されたメソッドは安全ではありません。不適切に使用した 合、JVMがクラッシュまたはメモリーが 損する 合があります。
      指定されたパス (ま ロードされていない 合)からライブラリをロードし、そのライブラリ内のシンボルのシンボル・ルックアップを作成します。 返されるライブラリ・ルックアップの存続期間は、指定されたアリーナによって制御されます。 たとえば、提供されたアリーナが限定されたアリーナである 合、提供された限定されたアリーナがclosedの 合、返されたルックアップに関連付けられたライブラリはアンロードされます。
      実装上のノート:
      Linuxでは、このファクトリ・メソッドによって提供される機能および返されるシンボル・ルックアップは、dlopendlsymおよびdlclose関数を使用して実装されます。
      パラメータ:
      path - シンボルを検索するライブラリのパス
      arena - 返されたルックアップから取得されたシンボルに関連付けられたアリーナ
      戻り値:
      指定されたパスを持つライブラリ内のシンボルを見つけるのに適した新しいシンボル・ルックアップ
      スロー:
      IllegalStateException - arena.scope().isAlive() == falseの 合
      WrongThreadException - arenaが限定アリーナで、このメソッドがアリーナの所有者スレッド以外のスレッドTからコールされる 合
      IllegalArgumentException - pathがデフォルトのファイル・システ の有効なライブラリを指していない 合
      IllegalCallerException - 呼出し元が、ネイティブ・アクセスが有効になっていないモジュール内にある 合