Sdk: Callback returning "Void" prints unhandled error exception

Created on 18 Jun 2019  路  9Comments  路  Source: dart-lang/sdk

The "void" return value is a null object in Dart, which is checked to be non-null. The check throws an exception, leading to:

==================== UNHANDLED EXCEPTION FROM FFI CALLBACK ====================
 ** Native callbacks should not throw exceptions because they cannot be
    propagated into native code. **
EXCEPTION: NoSuchMethodError: The method 'FfiCallback' was called on null.
Receiver: null
Tried calling: FfiCallback()
#0      FfiCallback (dart:ffi)
#1      FfiTrampoline (dart:ffi)
#2      Test.run (file:///usr/local/google/home/sjindel/src/dart-sdk/sdk/tests/ffi/function_callbacks_test.dart:38:32)
#3      main.<anonymous closure> (file:///usr/local/google/home/sjindel/src/dart-sdk/sdk/tests/ffi/function_callbacks_test.dart:196:30)
#4      List.forEach (dart:core-patch/growable_array.dart:278:8)
#5      main (file:///usr/local/google/home/sjindel/src/dart-sdk/sdk/tests/ffi/function_callbacks_test.dart:196:13)
<asynchronous suspension>
#6      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
#7      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)
area-vm library-ffi

Most helpful comment

The issue is still reproduced in Dart 2.7.0

All 9 comments

@sjindel-google, Hello. Is it fixed? I can still reproduce it on SDK 2.4.0
dart --version
Dart VM version: 2.4.0 (Wed Jun 19 11:53:45 2019 +0200) on "windows_x64"

I should be fixed, and we have tests for this now. Can you supply the code you're running which is giving an error?

Code

import 'dart:ffi';

typedef AddCbNative = Int32 Function(Pointer cb);
typedef AddCb = int Function(Pointer cb);

typedef Add = Void Function(Int32 a, Int32 b);

void add(int a, int b) {
  print('$a $b');
  return;
}

void main() {
  var library = DynamicLibrary.open("tets-dll.dll");
  var addcb = library.lookupFunction<AddCbNative, AddCb>("addcb");
  print(addcb(fromFunction<Add>(add)));
}

Library

#include "main.h"
extern "C" int DLL_EXPORT addcb(void (*add)(int, int))
{
  add(10, 20);
  return 7;
}

Error

==================== UNHANDLED EXCEPTION FROM FFI CALLBACK ====================
 ** Native callbacks should not throw exceptions because they cannot be
    propagated into native code. **
EXCEPTION: NoSuchMethodError: The method 'FfiCallback' was called on null.
Receiver: null
Tried calling: FfiCallback()
#0      FfiCallback (dart:ffi)
#1      FfiTrampoline (dart:ffi)
#2      main (file:///C:/projects/dart/ffi/bin/app_glfw.dart:17:14)
#3      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
#4      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)

Output

10 20
7

The problem has been fixed, you just need to upgrade your Dart or Flutter version.

@sjindel-google but I use 2.4.0. It is a latest.

I think you'll need to use the dev channel, since the fix isn't released in a stable Dart version yet.

We typically close issues when they have been fixed in our master branch, even though that fix may not yet be available to all our users.

@sjindel-google Thank you.

The issue is still reproduced in Dart 2.7.0

Hey @sjindel-google,
the issue still exists in Dart 2.7.1 and Dart 2.8.0-dev.16.0.
Dart VM version: 2.7.1 (Thu Jan 23 13:02:26 2020 +0100) on "linux_x64"

Dart VM version: 2.8.0-dev.16.0 (Thu Mar 19 12:20:19 2020 +0100) on "linux_x64"

For some reason, the exception does not appear when running directly from the commandline. If I run it with the debugger in VSCode:
Screenshot from 2020-03-22 18-19-38

It is also visible if I run with --observe
```dart --observe test.dart
Observatory listening on http://127.0.0.1:8181/gesA-KXHN7Y=/
10 20
vm-service: isolate (973544823160851) 'main' has no debugger attached and is paused due to exception. Connect to Observat
ory at http://127.0.0.1:8181/gesA-KXHN7Y=/ to debug.

![Screenshot_2020-03-22 Dart VM Observatory](https://user-images.githubusercontent.com/36953955/77249083-be181480-6c64-11ea-9e57-3025e6290046.png)

I only made minor changes to @rootext's code:

typedef void (*add)(int, int);

int addcb(add addfn) {
addfn(10, 20);
return 1;
}


import 'dart:ffi';.

typedef AddCbNative = Int32 Function(Pointer> cb);
typedef AddCb = int Function(Pointer> cb);

typedef Add = Void Function(Int32 a, Int32 b);

void add(int a, int b) {
print('$a $b');
return;
}

void main() {
var library = DynamicLibrary.open("./test.so");
var addcb = library.lookupFunction("addcb");
print(addcb(Pointer.fromFunction(add)));
}
```

Was this page helpful?
0 / 5 - 0 ratings