-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
dynamic_library.dart
114 lines (103 loc) · 4.66 KB
/
dynamic_library.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// 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});
}