| // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file | 
 | // for details. All rights reserved. Use of this source code is governed by a | 
 | // BSD-style license that can be found in the LICENSE file. | 
 |  | 
 | part of "dart:ffi"; | 
 |  | 
 | /// A dynamically loaded native library. | 
 | /// | 
 | /// A dynamically loaded library is a mapping from symbols to memory addresses. | 
 | /// These memory addresses can be accessed through [lookup]. | 
 | final class DynamicLibrary { | 
 |   /// Creates a [DynamicLibrary] holding all global symbols. | 
 |   /// | 
 |   /// Any symbol in a library currently loaded with global visibility | 
 |   /// (including the executable itself) may be resolved through this library. | 
 |   external factory DynamicLibrary.process(); | 
 |  | 
 |   /// Creates a [DynamicLibrary] containing all the symbols of the running | 
 |   /// executable. | 
 |   /// | 
 |   /// This is useful for using dart:ffi with static libraries. | 
 |   external factory DynamicLibrary.executable(); | 
 |  | 
 |   /// Loads a library file and provides access to its symbols. | 
 |   /// | 
 |   /// The [path] must refer to a native library file which can be successfully | 
 |   /// loaded. | 
 |   /// | 
 |   /// Calling this function multiple times with the same [path], even across | 
 |   /// different isolates, only loads the library into the DartVM process once. | 
 |   /// Multiple loads of the same library file produces [DynamicLibrary] objects | 
 |   /// which are equal (`==`), but not [identical]. | 
 |   external factory DynamicLibrary.open(String path); | 
 |  | 
 |   /// Looks up a symbol in the [DynamicLibrary] and returns its address in | 
 |   /// memory. | 
 |   /// | 
 |   /// Similar to the functionality of the | 
 |   /// [dlsym(3)](https://man7.org/linux/man-pages/man3/dlsym.3.html) system | 
 |   /// call. | 
 |   /// | 
 |   /// The symbol must be provided by the dynamic library. To check whether | 
 |   /// the library provides such symbol, use [providesSymbol]. | 
 |   external Pointer<T> lookup<T extends NativeType>(String symbolName); | 
 |  | 
 |   /// Checks whether this dynamic library provides a symbol with the given | 
 |   /// name. | 
 |   @Since('2.14') | 
 |   external bool providesSymbol(String symbolName); | 
 |  | 
 |   /// Closes this dynamic library. | 
 |   /// | 
 |   /// After calling [close], this library object can no longer be used for | 
 |   /// lookups. Further, this information is forwarded to the operating system, | 
 |   /// which may unload the library if there are no remaining references to it | 
 |   /// in the current process. | 
 |   /// | 
 |   /// Depending on whether another reference to this library has been opened, | 
 |   /// pointers and functions previously returned by [lookup] and | 
 |   /// [DynamicLibraryExtension.lookupFunction] may become invalid as well. | 
 |   @Since('3.1') | 
 |   external void close(); | 
 |  | 
 |   /// Dynamic libraries are equal if they load the same library. | 
 |   external bool operator ==(Object other); | 
 |  | 
 |   /// The hash code for a [DynamicLibrary] only depends on the loaded library. | 
 |   external int get hashCode; | 
 |  | 
 |   /// The opaque handle to the dynamic library. | 
 |   /// | 
 |   /// Similar to the return value of | 
 |   /// [dlopen(3)](https://man7.org/linux/man-pages/man3/dlopen.3.html). | 
 |   /// Can be used as arguments to other functions in the `dlopen` API | 
 |   /// through FFI calls. | 
 |   external Pointer<Void> get handle; | 
 | } | 
 |  | 
 | /// Method which must not be invoked dynamically. | 
 | extension DynamicLibraryExtension on DynamicLibrary { | 
 |   /// Looks up a native function and returns it as a Dart function. | 
 |   /// | 
 |   /// [T] is the C function signature, and [F] is the Dart function signature. | 
 |   /// | 
 |   /// For example: | 
 |   /// | 
 |   /// ```c | 
 |   /// int32_t add(int32_t a, int32_t b) { | 
 |   ///   return a + b; | 
 |   /// } | 
 |   /// ``` | 
 |   /// | 
 |   /// ```dart | 
 |   /// DynamicLibrary dylib = DynamicLibrary.executable(); | 
 |   /// final add = dylib.lookupFunction<Int32 Function(Int32, Int32), int Function(int, int)>( | 
 |   ///         'add'); | 
 |   /// ``` | 
 |   /// | 
 |   /// [isLeaf] specifies whether the function is a leaf function. Leaf functions | 
 |   /// are small, short-running, non-blocking functions which are not allowed to | 
 |   /// call back into Dart or use any Dart VM APIs. Leaf functions are invoked | 
 |   /// bypassing some of the heavier parts of the standard Dart-to-Native calling | 
 |   /// sequence which reduces the invocation overhead, making leaf calls faster | 
 |   /// than non-leaf calls. However, this implies that a thread executing a leaf | 
 |   /// function can't cooperate with the Dart runtime. A long running or blocking | 
 |   /// leaf function will delay any operation which requires synchronization | 
 |   /// between all threads associated with an isolate group until after the leaf | 
 |   /// function returns. For example, if one isolate in a group is trying to | 
 |   /// perform a GC and a second isolate is blocked in a leaf call, then the | 
 |   /// first isolate will have to pause and wait until this leaf call returns. | 
 |   external F lookupFunction<T extends Function, F extends Function>( | 
 |     String symbolName, { | 
 |     bool isLeaf = false, | 
 |   }); | 
 | } |