Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
dcharkes opened this issue Dec 21, 2021 · 1 comment
Open

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

dcharkes opened this issue Dec 21, 2021 · 1 comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-ffi

Comments

@dcharkes
Copy link
Contributor

dcharkes commented Dec 21, 2021

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:

@dcharkes dcharkes added area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-ffi labels Dec 21, 2021
@timsneath
Copy link
Contributor

That would be dreamy! 🥳

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-ffi
Projects
None yet
Development

No branches or pull requests

2 participants