@@ -22,19 +22,21 @@ final PosixCalloc posixCalloc =
22
22
23
23
typedef PosixFreeNative = Void Function (Pointer );
24
24
typedef PosixFree = void Function (Pointer );
25
- final PosixFree posixFree =
26
- stdlib.lookupFunction <PosixFreeNative , PosixFree >('free' );
25
+ final Pointer <NativeFunction <PosixFreeNative >> posixFreePointer =
26
+ stdlib.lookup ('free' );
27
+ final PosixFree posixFree = posixFreePointer.asFunction ();
27
28
28
- typedef WinCoTaskMemAllocNative = Pointer Function (Size cb );
29
- typedef WinCoTaskMemAlloc = Pointer Function (int cb );
29
+ typedef WinCoTaskMemAllocNative = Pointer Function (Size );
30
+ typedef WinCoTaskMemAlloc = Pointer Function (int );
30
31
final WinCoTaskMemAlloc winCoTaskMemAlloc =
31
32
stdlib.lookupFunction <WinCoTaskMemAllocNative , WinCoTaskMemAlloc >(
32
33
'CoTaskMemAlloc' );
33
34
34
- typedef WinCoTaskMemFreeNative = Void Function (Pointer pv);
35
- typedef WinCoTaskMemFree = void Function (Pointer pv);
36
- final WinCoTaskMemFree winCoTaskMemFree = stdlib
37
- .lookupFunction <WinCoTaskMemFreeNative , WinCoTaskMemFree >('CoTaskMemFree' );
35
+ typedef WinCoTaskMemFreeNative = Void Function (Pointer );
36
+ typedef WinCoTaskMemFree = void Function (Pointer );
37
+ final Pointer <NativeFunction <WinCoTaskMemFreeNative >> winCoTaskMemFreePointer =
38
+ stdlib.lookup ('CoTaskMemFree' );
39
+ final WinCoTaskMemFree winCoTaskMemFree = winCoTaskMemFreePointer.asFunction ();
38
40
39
41
/// Manages memory on the native heap.
40
42
///
@@ -43,8 +45,8 @@ final WinCoTaskMemFree winCoTaskMemFree = stdlib
43
45
///
44
46
/// For POSIX-based systems, this uses `malloc` and `free` . On Windows, it uses
45
47
/// `CoTaskMemAlloc` .
46
- class _MallocAllocator implements Allocator {
47
- const _MallocAllocator ();
48
+ final class MallocAllocator implements Allocator {
49
+ const MallocAllocator ._ ();
48
50
49
51
/// Allocates [byteCount] bytes of of unitialized memory on the native heap.
50
52
///
@@ -81,6 +83,37 @@ class _MallocAllocator implements Allocator {
81
83
posixFree (pointer);
82
84
}
83
85
}
86
+
87
+ /// Returns a pointer to a native free function.
88
+ ///
89
+ /// This function can be used to release memory allocated by [allocated]
90
+ /// from the native side. It can also be used as a finalization callback
91
+ /// passed to `NativeFinalizer` constructor or `Pointer.atTypedList`
92
+ /// method.
93
+ ///
94
+ /// For example to automatically free native memory when the Dart object
95
+ /// wrapping it is reclaimed by GC:
96
+ ///
97
+ /// ```dart
98
+ /// class Wrapper implements Finalizable {
99
+ /// static final finalizer = NativeFinalizer(malloc.nativeFree);
100
+ ///
101
+ /// final Pointer<Uint8> data;
102
+ ///
103
+ /// Wrapper() : data = malloc.allocate<Uint8>(length) {
104
+ /// finalizer.attach(this, data);
105
+ /// }
106
+ /// }
107
+ /// ```
108
+ ///
109
+ /// or to free native memory that is owned by a typed list:
110
+ ///
111
+ /// ```dart
112
+ /// malloc.allocate<Uint8>(n).asTypedList(n, finalizer: malloc.nativeFree)
113
+ /// ```
114
+ ///
115
+ Pointer <NativeFinalizerFunction > get nativeFree =>
116
+ Platform .isWindows ? winCoTaskMemFreePointer : posixFreePointer;
84
117
}
85
118
86
119
/// Manages memory on the native heap.
@@ -90,16 +123,16 @@ class _MallocAllocator implements Allocator {
90
123
///
91
124
/// For POSIX-based systems, this uses `malloc` and `free` . On Windows, it uses
92
125
/// `CoTaskMemAlloc` and `CoTaskMemFree` .
93
- const Allocator malloc = _MallocAllocator ();
126
+ const MallocAllocator malloc = MallocAllocator ._ ();
94
127
95
128
/// Manages memory on the native heap.
96
129
///
97
130
/// Initializes newly allocated memory to zero.
98
131
///
99
132
/// For POSIX-based systems, this uses `calloc` and `free` . On Windows, it uses
100
133
/// `CoTaskMemAlloc` and `CoTaskMemFree` .
101
- class _CallocAllocator implements Allocator {
102
- const _CallocAllocator ();
134
+ final class CallocAllocator implements Allocator {
135
+ const CallocAllocator ._ ();
103
136
104
137
/// Fills a block of memory with a specified value.
105
138
void _fillMemory (Pointer destination, int length, int fill) {
@@ -153,6 +186,37 @@ class _CallocAllocator implements Allocator {
153
186
posixFree (pointer);
154
187
}
155
188
}
189
+
190
+ /// Returns a pointer to a native free function.
191
+ ///
192
+ /// This function can be used to release memory allocated by [allocated]
193
+ /// from the native side. It can also be used as a finalization callback
194
+ /// passed to `NativeFinalizer` constructor or `Pointer.atTypedList`
195
+ /// method.
196
+ ///
197
+ /// For example to automatically free native memory when the Dart object
198
+ /// wrapping it is reclaimed by GC:
199
+ ///
200
+ /// ```dart
201
+ /// class Wrapper implements Finalizable {
202
+ /// static final finalizer = NativeFinalizer(calloc.nativeFree);
203
+ ///
204
+ /// final Pointer<Uint8> data;
205
+ ///
206
+ /// Wrapper() : data = calloc.allocate<Uint8>(length) {
207
+ /// finalizer.attach(this, data);
208
+ /// }
209
+ /// }
210
+ /// ```
211
+ ///
212
+ /// or to free native memory that is owned by a typed list:
213
+ ///
214
+ /// ```dart
215
+ /// calloc.allocate<Uint8>(n).asTypedList(n, finalizer: calloc.nativeFree)
216
+ /// ```
217
+ ///
218
+ Pointer <NativeFinalizerFunction > get nativeFree =>
219
+ Platform .isWindows ? winCoTaskMemFreePointer : posixFreePointer;
156
220
}
157
221
158
222
/// Manages memory on the native heap.
@@ -162,4 +226,4 @@ class _CallocAllocator implements Allocator {
162
226
///
163
227
/// For POSIX-based systems, this uses `calloc` and `free` . On Windows, it uses
164
228
/// `CoTaskMemAlloc` and `CoTaskMemFree` .
165
- const Allocator calloc = _CallocAllocator ();
229
+ const CallocAllocator calloc = CallocAllocator ._ ();
0 commit comments