Skip to content

[vm/ffi] Unwrapping Strings in FFI calls #47992

Open
@dcharkes

Description

@dcharkes

We could consider supporting unwrapping Strings to Pointers in FFI calls, this would make the following code much more ergonomic.

  final messageBox = dl.lookupFunction<
    Pointer Function(Pointer, Pointer<Utf16>, Pointer<Utf16>, Int32),
    Pointer Function(Pointer, Pointer<Utf16>, Pointer<Utf16>, int)>();

  final result = using((Arena arena) {
    final message =
        'This is not really an error, but we are pretending for the sake '
                'of this test.\n\nResource error.\nDo you want to try again?'
            .toNativeUtf16(allocator: arena);
    final caption = 'Dart MessageBox Test'.toNativeUtf16(allocator: arena);
    return messageBox(
        NULL,
        message,
        caption,
        MB_ICONWARNING | // Warning
            MB_CANCELTRYCONTINUE | // Action button
            MB_DEFBUTTON2 // Second button is the default
        );
  });

New code, with the dart signature of messageBox having String rather than Pointer<Utf16> as argument types:

    final messageBox = dl.lookupFunction<
      Pointer Function(Pointer, Pointer<Utf16>, Pointer<Utf16>, Int32),
      Pointer Function(Pointer, String, String, int)>();

    final message =
        'This is not really an error, but we are pretending for the sake '
                'of this test.\n\nResource error.\nDo you want to try again?';
    final caption = 'Dart MessageBox Test';
    final result = messageBox(
        NULL,
        message,
        caption,
        MB_ICONWARNING | // Warning
            MB_CANCELTRYCONTINUE | // Action button
            MB_DEFBUTTON2 // Second button is the default
        );

We would have to specify the encoding expected, which we could do with the type argument of Pointer. The encoding would work exactly as package:ffi's toNativeUtf8() and toNativeUtf16() extension methods.

The life-time would be duration of the FFI call. (And for callbacks until the GC collects the String copied to Dart memory.)

For leaf-calls, if the string happens to be in the right encoding, we could pass the interior pointer. #39787 (comment)

One of the questions to answer is how to select the transform. Do we want support for more encodings than Utf8/Utf16? Do we always zero-terminate? And because the Utf16 and Utf8 are in package:ffi, do we move them?

Related:

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-vmUse area-vm for VM related issues, including code coverage, and the AOT and JIT backends.library-ffi

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions