blob: 968c555be68301d189033706c74b704b23c95163 [file] [log] [blame]
// 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
/**
* Foreign Function Interface for interoperability with the C programming language.
*
* For further details, please see: https://dart.dev/server/c-interop
*
* {@category VM}
*/
library dart.ffi;
import 'dart:_internal' show Since;
import 'dart:isolate';
import 'dart:typed_data';
part 'abi.dart';
part 'abi_specific.dart';
part 'native_type.dart';
part 'native_finalizer.dart';
part 'allocation.dart';
part 'annotations.dart';
part 'c_type.dart';
part 'dynamic_library.dart';
part 'struct.dart';
part 'union.dart';
/// Number of bytes used by native type T.
///
/// Includes padding and alignment of structs.
///
/// This function must be invoked with a compile-time constant [T].
external int sizeOf<T extends NativeType>();
/// Represents a pointer into the native C memory corresponding to 'NULL', e.g.
/// a pointer with address 0.
final Pointer<Never> nullptr = Pointer.fromAddress(0);
/// Represents a pointer into the native C memory. Cannot be extended.
@pragma('vm:entry-point')
class Pointer<T extends NativeType> extends NativeType {
/// Construction from raw integer.
external factory Pointer.fromAddress(int ptr);
/// Convert Dart function to a C function pointer, automatically marshalling
/// the arguments and return value
///
/// If an exception is thrown while calling `f()`, the native function will
/// return `exceptionalReturn`, which must be assignable to return type of `f`.
///
/// The returned function address can only be invoked on the mutator (main)
/// thread of the current isolate. It will abort the process if invoked on any
/// other thread.
///
/// The pointer returned will remain alive for the duration of the current
/// isolate's lifetime. After the isolate it was created in is terminated,
/// invoking it from native code will cause undefined behavior.
///
/// Does not accept dynamic invocations -- where the type of the receiver is
/// [dynamic].
external static Pointer<NativeFunction<T>> fromFunction<T extends Function>(
@DartRepresentationOf('T') Function f,
[Object? exceptionalReturn]);
/// Access to the raw pointer value.
/// On 32-bit systems, the upper 32-bits of the result are 0.
external int get address;
/// Pointer arithmetic (takes element size into account).
///
/// This method must be invoked with a compile-time constant [T].
///
/// Does not accept dynamic invocations -- where the type of the receiver is
/// [dynamic].
external Pointer<T> elementAt(int index);
/// Cast Pointer<T> to a Pointer<V>.
external Pointer<U> cast<U extends NativeType>();
/// Equality for Pointers only depends on their address.
bool operator ==(Object other) {
if (other is! Pointer) return false;
Pointer otherPointer = other;
return address == otherPointer.address;
}
/// The hash code for a Pointer only depends on its address.
int get hashCode {
return address.hashCode;
}
}
/// A fixed-sized array of [T]s.
class Array<T extends NativeType> extends NativeType {
/// Const constructor to specify [Array] dimensions in [Struct]s.
///
/// ```dart
/// class MyStruct extends Struct {
/// @Array(8)
/// external Array<Uint8> inlineArray;
///
/// @Array(2, 2, 2)
/// external Array<Array<Array<Uint8>>> threeDimensionalInlineArray;
/// }
/// ```
///
/// Do not invoke in normal code.
const factory Array(int dimension1,
[int dimension2,
int dimension3,
int dimension4,
int dimension5]) = _ArraySize<T>;
/// Const constructor to specify [Array] dimensions in [Struct]s.
///
/// ```dart
/// class MyStruct extends Struct {
/// @Array.multi([2, 2, 2])
/// external Array<Array<Array<Uint8>>> threeDimensionalInlineArray;
///
/// @Array.multi([2, 2, 2, 2, 2, 2, 2, 2])
/// external Array<Array<Array<Array<Array<Array<Array<Array<Uint8>>>>>>>> eightDimensionalInlineArray;
/// }
/// ```
///
/// Do not invoke in normal code.
const factory Array.multi(List<int> dimensions) = _ArraySize<T>.multi;
}
class _ArraySize<T extends NativeType> implements Array<T> {
final int? dimension1;
final int? dimension2;
final int? dimension3;
final int? dimension4;
final int? dimension5;
final List<int>? dimensions;
const _ArraySize(this.dimension1,
[this.dimension2, this.dimension3, this.dimension4, this.dimension5])
: dimensions = null;
const _ArraySize.multi(this.dimensions)
: dimension1 = null,
dimension2 = null,
dimension3 = null,
dimension4 = null,
dimension5 = null;
}
/// Extension on [Pointer] specialized for the type argument [NativeFunction].
extension NativeFunctionPointer<NF extends Function>
on Pointer<NativeFunction<NF>> {
/// Convert to Dart function, automatically marshalling the arguments
/// and return value.
external DF asFunction<@DartRepresentationOf('NF') DF extends Function>(
{bool isLeaf: false});
}
//
// The following code is generated, do not edit by hand.
//
// Code generated by `runtime/tools/ffi/sdk_lib_ffi_generator.dart`.
//
/// Extension on [Pointer] specialized for the type argument [Int8].
extension Int8Pointer on Pointer<Int8> {
/// The 8-bit two's complement integer at [address].
///
/// A Dart integer is truncated to 8 bits (as if by `.toSigned(8)`) before
/// being stored, and the 8-bit value is sign-extended when it is loaded.
external int get value;
external void set value(int value);
/// The 8-bit two's complement integer at `address + index`.
///
/// A Dart integer is truncated to 8 bits (as if by `.toSigned(8)`) before
/// being stored, and the 8-bit value is sign-extended when it is loaded.
external int operator [](int index);
/// The 8-bit two's complement integer at `address + index`.
///
/// A Dart integer is truncated to 8 bits (as if by `.toSigned(8)`) before
/// being stored, and the 8-bit value is sign-extended when it is loaded.
external void operator []=(int index, int value);
/// Creates a typed list view backed by memory in the address space.
///
/// The returned view will allow access to the memory range from [address]
/// to `address + length`.
///
/// The user has to ensure the memory range is accessible while using the
/// returned list.
external Int8List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Int16].
extension Int16Pointer on Pointer<Int16> {
/// The 16-bit two's complement integer at [address].
///
/// A Dart integer is truncated to 16 bits (as if by `.toSigned(16)`) before
/// being stored, and the 16-bit value is sign-extended when it is loaded.
///
/// The [address] must be 2-byte aligned.
external int get value;
external void set value(int value);
/// The 16-bit two's complement integer at `address + 2 * index`.
///
/// A Dart integer is truncated to 16 bits (as if by `.toSigned(16)`) before
/// being stored, and the 16-bit value is sign-extended when it is loaded.
///
/// The [address] must be 2-byte aligned.
external int operator [](int index);
/// The 16-bit two's complement integer at `address + 2 * index`.
///
/// A Dart integer is truncated to 16 bits (as if by `.toSigned(16)`) before
/// being stored, and the 16-bit value is sign-extended when it is loaded.
///
/// The [address] must be 2-byte aligned.
external void operator []=(int index, int value);
/// Creates a typed list view backed by memory in the address space.
///
/// The returned view will allow access to the memory range from [address]
/// to `address + 2 * length`.
///
/// The user has to ensure the memory range is accessible while using the
/// returned list.
///
/// The [address] must be 2-byte aligned.
external Int16List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Int32].
extension Int32Pointer on Pointer<Int32> {
/// The 32-bit two's complement integer at [address].
///
/// A Dart integer is truncated to 32 bits (as if by `.toSigned(32)`) before
/// being stored, and the 32-bit value is sign-extended when it is loaded.
///
/// The [address] must be 4-byte aligned.
external int get value;
external void set value(int value);
/// The 32-bit two's complement integer at `address + 4 * index`.
///
/// A Dart integer is truncated to 32 bits (as if by `.toSigned(32)`) before
/// being stored, and the 32-bit value is sign-extended when it is loaded.
///
/// The [address] must be 4-byte aligned.
external int operator [](int index);
/// The 32-bit two's complement integer at `address + 4 * index`.
///
/// A Dart integer is truncated to 32 bits (as if by `.toSigned(32)`) before
/// being stored, and the 32-bit value is sign-extended when it is loaded.
///
/// The [address] must be 4-byte aligned.
external void operator []=(int index, int value);
/// Creates a typed list view backed by memory in the address space.
///
/// The returned view will allow access to the memory range from [address]
/// to `address + 4 * length`.
///
/// The user has to ensure the memory range is accessible while using the
/// returned list.
///
/// The [address] must be 4-byte aligned.
external Int32List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Int64].
extension Int64Pointer on Pointer<Int64> {
/// The 64-bit two's complement integer at [address].
///
/// The [address] must be 8-byte aligned.
external int get value;
external void set value(int value);
/// The 64-bit two's complement integer at `address + 8 * index`.
///
/// The [address] must be 8-byte aligned.
external int operator [](int index);
/// The 64-bit two's complement integer at `address + 8 * index`.
///
/// The [address] must be 8-byte aligned.
external void operator []=(int index, int value);
/// Creates a typed list view backed by memory in the address space.
///
/// The returned view will allow access to the memory range from [address]
/// to `address + 8 * length`.
///
/// The user has to ensure the memory range is accessible while using the
/// returned list.
///
/// The [address] must be 8-byte aligned.
external Int64List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Uint8].
extension Uint8Pointer on Pointer<Uint8> {
/// The 8-bit unsigned integer at [address].
///
/// A Dart integer is truncated to 8 bits (as if by `.toUnsigned(8)`) before
/// being stored, and the 8-bit value is zero-extended when it is loaded.
external int get value;
external void set value(int value);
/// The 8-bit unsigned integer at `address + index`.
///
/// A Dart integer is truncated to 8 bits (as if by `.toUnsigned(8)`) before
/// being stored, and the 8-bit value is zero-extended when it is loaded.
external int operator [](int index);
/// The 8-bit unsigned integer at `address + index`.
///
/// A Dart integer is truncated to 8 bits (as if by `.toUnsigned(8)`) before
/// being stored, and the 8-bit value is zero-extended when it is loaded.
external void operator []=(int index, int value);
/// Creates a typed list view backed by memory in the address space.
///
/// The returned view will allow access to the memory range from [address]
/// to `address + length`.
///
/// The user has to ensure the memory range is accessible while using the
/// returned list.
external Uint8List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Uint16].
extension Uint16Pointer on Pointer<Uint16> {
/// The 16-bit unsigned integer at [address].
///
/// A Dart integer is truncated to 16 bits (as if by `.toUnsigned(16)`) before
/// being stored, and the 16-bit value is zero-extended when it is loaded.
///
/// The [address] must be 2-byte aligned.
external int get value;
external void set value(int value);
/// The 16-bit unsigned integer at `address + 2 * index`.
///
/// A Dart integer is truncated to 16 bits (as if by `.toUnsigned(16)`) before
/// being stored, and the 16-bit value is zero-extended when it is loaded.
///
/// The [address] must be 2-byte aligned.
external int operator [](int index);
/// The 16-bit unsigned integer at `address + 2 * index`.
///
/// A Dart integer is truncated to 16 bits (as if by `.toUnsigned(16)`) before
/// being stored, and the 16-bit value is zero-extended when it is loaded.
///
/// The [address] must be 2-byte aligned.
external void operator []=(int index, int value);
/// Creates a typed list view backed by memory in the address space.
///
/// The returned view will allow access to the memory range from [address]
/// to `address + 2 * length`.
///
/// The user has to ensure the memory range is accessible while using the
/// returned list.
///
/// The [address] must be 2-byte aligned.
external Uint16List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Uint32].
extension Uint32Pointer on Pointer<Uint32> {
/// The 32-bit unsigned integer at [address].
///
/// A Dart integer is truncated to 32 bits (as if by `.toUnsigned(32)`) before
/// being stored, and the 32-bit value is zero-extended when it is loaded.
///
/// The [address] must be 4-byte aligned.
external int get value;
external void set value(int value);
/// The 32-bit unsigned integer at `address + 4 * index`.
///
/// A Dart integer is truncated to 32 bits (as if by `.toUnsigned(32)`) before
/// being stored, and the 32-bit value is zero-extended when it is loaded.
///
/// The [address] must be 4-byte aligned.
external int operator [](int index);
/// The 32-bit unsigned integer at `address + 4 * index`.
///
/// A Dart integer is truncated to 32 bits (as if by `.toUnsigned(32)`) before
/// being stored, and the 32-bit value is zero-extended when it is loaded.
///
/// The [address] must be 4-byte aligned.
external void operator []=(int index, int value);
/// Creates a typed list view backed by memory in the address space.
///
/// The returned view will allow access to the memory range from [address]
/// to `address + 4 * length`.
///
/// The user has to ensure the memory range is accessible while using the
/// returned list.
///
/// The [address] must be 4-byte aligned.
external Uint32List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Uint64].
extension Uint64Pointer on Pointer<Uint64> {
/// The 64-bit unsigned integer at [address].
///
/// The [address] must be 8-byte aligned.
external int get value;
external void set value(int value);
/// The 64-bit unsigned integer at `address + 8 * index`.
///
/// The [address] must be 8-byte aligned.
external int operator [](int index);
/// The 64-bit unsigned integer at `address + 8 * index`.
///
/// The [address] must be 8-byte aligned.
external void operator []=(int index, int value);
/// Creates a typed list view backed by memory in the address space.
///
/// The returned view will allow access to the memory range from [address]
/// to `address + 8 * length`.
///
/// The user has to ensure the memory range is accessible while using the
/// returned list.
///
/// The [address] must be 8-byte aligned.
external Uint64List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Float].
extension FloatPointer on Pointer<Float> {
/// The float at [address].
///
/// A Dart double loses precision before being stored, and the float value is
/// converted to a double when it is loaded.
///
/// The [address] must be 4-byte aligned.
external double get value;
external void set value(double value);
/// The float at `address + 4 * index`.
///
/// A Dart double loses precision before being stored, and the float value is
/// converted to a double when it is loaded.
///
/// The [address] must be 4-byte aligned.
external double operator [](int index);
/// The float at `address + 4 * index`.
///
/// A Dart double loses precision before being stored, and the float value is
/// converted to a double when it is loaded.
///
/// The [address] must be 4-byte aligned.
external void operator []=(int index, double value);
/// Creates a typed list view backed by memory in the address space.
///
/// The returned view will allow access to the memory range from [address]
/// to `address + 4 * length`.
///
/// The user has to ensure the memory range is accessible while using the
/// returned list.
///
/// The [address] must be 4-byte aligned.
external Float32List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Double].
extension DoublePointer on Pointer<Double> {
/// The double at [address].
///
/// The [address] must be 8-byte aligned.
external double get value;
external void set value(double value);
/// The double at `address + 8 * index`.
///
/// The [address] must be 8-byte aligned.
external double operator [](int index);
/// The double at `address + 8 * index`.
///
/// The [address] must be 8-byte aligned.
external void operator []=(int index, double value);
/// Creates a typed list view backed by memory in the address space.
///
/// The returned view will allow access to the memory range from [address]
/// to `address + 8 * length`.
///
/// The user has to ensure the memory range is accessible while using the
/// returned list.
///
/// The [address] must be 8-byte aligned.
external Float64List asTypedList(int length);
}
/// Extension on [Pointer] specialized for the type argument [Bool].
extension BoolPointer on Pointer<Bool> {
/// The bool at [address].
external bool get value;
external void set value(bool value);
/// The bool at `address + index`.
external bool operator [](int index);
/// The bool at `address + index`.
external void operator []=(int index, bool value);
}
/// Bounds checking indexing methods on [Array]s of [Int8].
extension Int8Array on Array<Int8> {
external int operator [](int index);
external void operator []=(int index, int value);
}
/// Bounds checking indexing methods on [Array]s of [Int16].
extension Int16Array on Array<Int16> {
external int operator [](int index);
external void operator []=(int index, int value);
}
/// Bounds checking indexing methods on [Array]s of [Int32].
extension Int32Array on Array<Int32> {
external int operator [](int index);
external void operator []=(int index, int value);
}
/// Bounds checking indexing methods on [Array]s of [Int64].
extension Int64Array on Array<Int64> {
external int operator [](int index);
external void operator []=(int index, int value);
}
/// Bounds checking indexing methods on [Array]s of [Uint8].
extension Uint8Array on Array<Uint8> {
external int operator [](int index);
external void operator []=(int index, int value);
}
/// Bounds checking indexing methods on [Array]s of [Uint16].
extension Uint16Array on Array<Uint16> {
external int operator [](int index);
external void operator []=(int index, int value);
}
/// Bounds checking indexing methods on [Array]s of [Uint32].
extension Uint32Array on Array<Uint32> {
external int operator [](int index);
external void operator []=(int index, int value);
}
/// Bounds checking indexing methods on [Array]s of [Uint64].
extension Uint64Array on Array<Uint64> {
external int operator [](int index);
external void operator []=(int index, int value);
}
/// Bounds checking indexing methods on [Array]s of [Float].
extension FloatArray on Array<Float> {
external double operator [](int index);
external void operator []=(int index, double value);
}
/// Bounds checking indexing methods on [Array]s of [Double].
extension DoubleArray on Array<Double> {
external double operator [](int index);
external void operator []=(int index, double value);
}
/// Bounds checking indexing methods on [Array]s of [Bool].
extension BoolArray on Array<Bool> {
external bool operator [](int index);
external void operator []=(int index, bool value);
}
//
// End of generated code.
//
/// Extension on [Pointer] specialized for the type argument [Pointer].
extension PointerPointer<T extends NativeType> on Pointer<Pointer<T>> {
/// The pointer at [address].
///
/// A [Pointer] is unboxed before being stored (as if by `.address`), and the
/// pointer is boxed (as if by `Pointer.fromAddress`) when loaded.
///
/// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit
/// platforms the [address] must be 8-byte aligned.
external Pointer<T> get value;
external void set value(Pointer<T> value);
/// Load a Dart value from this location offset by [index].
///
/// A [Pointer] is unboxed before being stored (as if by `.address`), and the
/// pointer is boxed (as if by `Pointer.fromAddress`) when loaded.
///
/// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit
/// platforms the [address] must be 8-byte aligned.
external Pointer<T> operator [](int index);
/// Store a Dart value into this location offset by [index].
///
/// A [Pointer] is unboxed before being stored (as if by `.address`), and the
/// pointer is boxed (as if by `Pointer.fromAddress`) when loaded.
///
/// On 32-bit platforms the [address] must be 4-byte aligned, and on 64-bit
/// platforms the [address] must be 8-byte aligned.
external void operator []=(int index, Pointer<T> value);
}
/// Extension on [Pointer] specialized for the type argument [Struct].
extension StructPointer<T extends Struct> on Pointer<T> {
/// A Dart view of the struct referenced by this pointer.
///
/// Reading [ref] creates a reference accessing the fields of this struct
/// backed by native memory at [address].
/// The [address] must be aligned according to the struct alignment rules of
/// the platform.
///
/// Assigning to [ref] copies contents of the struct into the native memory
/// starting at [address].
///
/// This extension method must be invoked on a receiver of type `Pointer<T>`
/// where `T` is a compile-time constant type.
external T get ref;
external set ref(T value);
/// Creates a reference to access the fields of this struct backed by native
/// memory at `address + sizeOf<T>() * index`.
///
/// The [address] must be aligned according to the struct alignment rules of
/// the platform.
///
/// This extension method must be invoked on a receiver of type `Pointer<T>`
/// where `T` is a compile-time constant type.
external T operator [](int index);
/// Copies the [value] struct into native memory, starting at
/// `address * sizeOf<T>() * index`.
///
/// This extension method must be invoked on a receiver of type `Pointer<T>`
/// where `T` is a compile-time constant type.
external void operator []=(int index, T value);
}
/// Extension on [Pointer] specialized for the type argument [Union].
extension UnionPointer<T extends Union> on Pointer<T> {
/// A Dart view of the union referenced by this pointer.
///
/// Reading [ref] creates a reference accessing the fields of this union
/// backed by native memory at [address].
/// The [address] must be aligned according to the union alignment rules of
/// the platform.
///
/// Assigning to [ref] copies contents of the union into the native memory
/// starting at [address].
///
/// This extension method must be invoked on a receiver of type `Pointer<T>`
/// where `T` is a compile-time constant type.
external T get ref;
external set ref(T value);
/// Creates a reference to access the fields of this union backed by native
/// memory at `address + sizeOf<T>() * index`.
///
/// The [address] must be aligned according to the union alignment rules of
/// the platform.
///
/// This extension method must be invoked on a receiver of type `Pointer<T>`
/// where `T` is a compile-time constant type.
external T operator [](int index);
/// Copies the [value] union into native memory, starting at
/// `address * sizeOf<T>() * index`.
///
/// This extension method must be invoked on a receiver of type `Pointer<T>`
/// where `T` is a compile-time constant type.
external void operator []=(int index, T value);
}
/// Extension on [Pointer] specialized for the type argument
/// [AbiSpecificInteger].
extension AbiSpecificIntegerPointer<T extends AbiSpecificInteger>
on Pointer<T> {
/// The integer at [address].
external int get value;
external void set value(int value);
/// The integer at `address + sizeOf<T>() * index`.
external int operator [](int index);
/// The integer at `address + sizeOf<T>() * index`.
external void operator []=(int index, int value);
}
/// Bounds checking indexing methods on [Array]s of [Pointer].
extension PointerArray<T extends NativeType> on Array<Pointer<T>> {
external Pointer<T> operator [](int index);
external void operator []=(int index, Pointer<T> value);
}
/// Bounds checking indexing methods on [Array]s of [Struct].
extension StructArray<T extends Struct> on Array<T> {
/// This extension method must be invoked on a receiver of type `Pointer<T>`
/// where `T` is a compile-time constant type.
external T operator [](int index);
}
/// Bounds checking indexing methods on [Array]s of [Union].
extension UnionArray<T extends Union> on Array<T> {
/// This extension method must be invoked on a receiver of type `Pointer<T>`
/// where `T` is a compile-time constant type.
external T operator [](int index);
}
/// Bounds checking indexing methods on [Array]s of [Array].
extension ArrayArray<T extends NativeType> on Array<Array<T>> {
external Array<T> operator [](int index);
external void operator []=(int index, Array<T> value);
}
/// Bounds checking indexing methods on [Array]s of [AbiSpecificInteger].
extension AbiSpecificIntegerArray on Array<AbiSpecificInteger> {
external int operator [](int index);
external void operator []=(int index, int value);
}
/// Extension to retrieve the native `Dart_Port` from a [SendPort].
extension NativePort on SendPort {
/// The native port of this [SendPort].
///
/// The returned native port can for example be used by C code to post
/// messages to the connected [ReceivePort] via `Dart_PostCObject()` - see
/// `dart_native_api.h`.
external int get nativePort;
}
/// Opaque, not exposing it's members.
class Dart_CObject extends Opaque {}
typedef Dart_NativeMessageHandler = Void Function(Int64, Pointer<Dart_CObject>);
/// Utilities for accessing the Dart VM API from Dart code or
/// from C code via `dart_api_dl.h`.
abstract class NativeApi {
/// On breaking changes the major version is increased.
///
/// The versioning covers the API surface in `dart_api_dl.h`.
external static int get majorVersion;
/// On backwards compatible changes the minor version is increased.
///
/// The versioning covers the API surface in `dart_api_dl.h`.
external static int get minorVersion;
/// A function pointer to
/// `bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message)`
/// in `dart_native_api.h`.
external static Pointer<
NativeFunction<Int8 Function(Int64, Pointer<Dart_CObject>)>>
get postCObject;
/// A function pointer to
/// ```c
/// Dart_Port Dart_NewNativePort(const char* name,
/// Dart_NativeMessageHandler handler,
/// bool handle_concurrently)
/// ```
/// in `dart_native_api.h`.
external static Pointer<
NativeFunction<
Int64 Function(
Pointer<Uint8>,
Pointer<NativeFunction<Dart_NativeMessageHandler>>,
Int8)>> get newNativePort;
/// A function pointer to
/// `bool Dart_CloseNativePort(Dart_Port native_port_id)`
/// in `dart_native_api.h`.
external static Pointer<NativeFunction<Int8 Function(Int64)>>
get closeNativePort;
/// Pass this to `Dart_InitializeApiDL` in your native code to enable using the
/// symbols in `dart_api_dl.h`.
external static Pointer<Void> get initializeApiDLData;
}
/// Annotation to be used for marking an external function as FFI native.
///
/// Example:
///```dart template:top
/// @FfiNative<Int64 Function(Int64, Int64)>('FfiNative_Sum', isLeaf:true)
/// external int sum(int a, int b);
///```
/// Calling such functions will throw an exception if no resolver
/// was set on the library or the resolver failed to resolve the name.
///
/// See `Dart_SetFfiNativeResolver` in `dart_api.h`
///
/// NOTE: This is an experimental feature and may change in the future.
class FfiNative<T> {
final String nativeName;
final bool isLeaf;
const FfiNative(this.nativeName, {this.isLeaf: false});
}
// Bootstrapping native for getting the FFI native C function pointer to look
// up the FFI resolver.
@pragma('vm:external-name', 'Ffi_GetFfiNativeResolver')
external Pointer<NativeFunction<IntPtr Function(Handle, Handle, IntPtr)>>
_get_ffi_native_resolver<T extends NativeFunction>();
// Resolver for FFI Native C function pointers.
@pragma('vm:entry-point')
final _ffi_resolver = _get_ffi_native_resolver<
NativeFunction<IntPtr Function(Handle, Handle, IntPtr)>>()
.asFunction<int Function(Object, Object, int)>();