Skip to content
This repository has been archived by the owner on Jan 17, 2024. It is now read-only.

Expose pointer to free from allocators #203

Merged
merged 6 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
matrix:
# Add macos-latest and/or windows-latest if relevant for this package.
os: [ubuntu-latest]
sdk: [2.17.0, dev]
sdk: [3.0.0, dev]
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 2.1.0

- Require Dart 3.0.0 or greater.
- Expose native equivalent to `free` (`nativeFree`) from `malloc` and
`calloc` allocators.

## 2.0.2

- Fixed a typo in a doc comment.
Expand Down
48 changes: 34 additions & 14 deletions lib/src/allocation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,21 @@ final PosixCalloc posixCalloc =

typedef PosixFreeNative = Void Function(Pointer);
typedef PosixFree = void Function(Pointer);
final PosixFree posixFree =
stdlib.lookupFunction<PosixFreeNative, PosixFree>('free');
final Pointer<NativeFunction<PosixFreeNative>> posixFreePointer =
stdlib.lookup('free');
final PosixFree posixFree = posixFreePointer.asFunction();

typedef WinCoTaskMemAllocNative = Pointer Function(Size cb);
typedef WinCoTaskMemAlloc = Pointer Function(int cb);
typedef WinCoTaskMemAllocNative = Pointer Function(Size);
typedef WinCoTaskMemAlloc = Pointer Function(int);
final WinCoTaskMemAlloc winCoTaskMemAlloc =
stdlib.lookupFunction<WinCoTaskMemAllocNative, WinCoTaskMemAlloc>(
'CoTaskMemAlloc');

typedef WinCoTaskMemFreeNative = Void Function(Pointer pv);
typedef WinCoTaskMemFree = void Function(Pointer pv);
final WinCoTaskMemFree winCoTaskMemFree = stdlib
.lookupFunction<WinCoTaskMemFreeNative, WinCoTaskMemFree>('CoTaskMemFree');
typedef WinCoTaskMemFreeNative = Void Function(Pointer);
typedef WinCoTaskMemFree = void Function(Pointer);
mraleph marked this conversation as resolved.
Show resolved Hide resolved
final Pointer<NativeFunction<WinCoTaskMemFreeNative>> winCoTaskMemFreePointer =
stdlib.lookup('CoTaskMemFree');
final WinCoTaskMemFree winCoTaskMemFree = winCoTaskMemFreePointer.asFunction();

/// Manages memory on the native heap.
///
Expand All @@ -43,8 +45,8 @@ final WinCoTaskMemFree winCoTaskMemFree = stdlib
///
/// For POSIX-based systems, this uses `malloc` and `free`. On Windows, it uses
/// `CoTaskMemAlloc`.
class _MallocAllocator implements Allocator {
const _MallocAllocator();
final class MallocAllocator implements Allocator {
const MallocAllocator._();

/// Allocates [byteCount] bytes of of unitialized memory on the native heap.
///
Expand Down Expand Up @@ -81,6 +83,15 @@ class _MallocAllocator implements Allocator {
posixFree(pointer);
}
}

/// Returns a pointer to a native free function.
///
/// This function can be used to release memory allocated by [allocated]
/// from the native side. It can also be used as a finalization callback
/// passed to `NativeFinalizer` constructor or `Pointer.atTypedList`
/// method.
Pointer<NativeFinalizerFunction> get nativeFree =>
Platform.isWindows ? winCoTaskMemFreePointer : posixFreePointer;
}

/// Manages memory on the native heap.
Expand All @@ -90,16 +101,16 @@ class _MallocAllocator implements Allocator {
///
/// For POSIX-based systems, this uses `malloc` and `free`. On Windows, it uses
/// `CoTaskMemAlloc` and `CoTaskMemFree`.
const Allocator malloc = _MallocAllocator();
const MallocAllocator malloc = MallocAllocator._();

/// Manages memory on the native heap.
///
/// Initializes newly allocated memory to zero.
///
/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
/// `CoTaskMemAlloc` and `CoTaskMemFree`.
class _CallocAllocator implements Allocator {
const _CallocAllocator();
final class CallocAllocator implements Allocator {
const CallocAllocator._();

/// Fills a block of memory with a specified value.
void _fillMemory(Pointer destination, int length, int fill) {
Expand Down Expand Up @@ -153,6 +164,15 @@ class _CallocAllocator implements Allocator {
posixFree(pointer);
}
}

/// Returns a pointer to a native free function.
///
/// This function can be used to release memory allocated by [allocated]
/// from the native side. It can also be used as a finalization callback
/// passed to `NativeFinalizer` constructor or `Pointer.atTypedList`
/// method.
mraleph marked this conversation as resolved.
Show resolved Hide resolved
Pointer<NativeFinalizerFunction> get nativeFree =>
Platform.isWindows ? winCoTaskMemFreePointer : posixFreePointer;
}

/// Manages memory on the native heap.
Expand All @@ -162,4 +182,4 @@ class _CallocAllocator implements Allocator {
///
/// For POSIX-based systems, this uses `calloc` and `free`. On Windows, it uses
/// `CoTaskMemAlloc` and `CoTaskMemFree`.
const Allocator calloc = _CallocAllocator();
const CallocAllocator calloc = CallocAllocator._();
2 changes: 1 addition & 1 deletion lib/src/utf16.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import 'package:ffi/ffi.dart';
/// through a `Pointer<Utf16>` representing the entire array. This pointer is
/// the equivalent of a char pointer (`const wchar_t*`) in C code. The
/// individual UTF-16 code units are stored in native byte order.
class Utf16 extends Opaque {}
final class Utf16 extends Opaque {}

/// Extension method for converting a`Pointer<Utf16>` to a [String].
extension Utf16Pointer on Pointer<Utf16> {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/utf8.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import 'package:ffi/ffi.dart';
/// The Utf8 type itself has no functionality, it's only intended to be used
/// through a `Pointer<Utf8>` representing the entire array. This pointer is
/// the equivalent of a char pointer (`const char*`) in C code.
class Utf8 extends Opaque {}
final class Utf8 extends Opaque {}

/// Extension method for converting a`Pointer<Utf8>` to a [String].
extension Utf8Pointer on Pointer<Utf8> {
Expand Down
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: ffi
version: 2.0.2
version: 2.1.0
description: Utilities for working with Foreign Function Interface (FFI) code.
repository: https://github.com/dart-lang/ffi

Expand All @@ -9,7 +9,7 @@ topics:
- codegen

environment:
sdk: '>=2.17.0 <4.0.0'
sdk: '>=3.0.0 <4.0.0'

dev_dependencies:
test: ^1.21.2
Expand Down