• Github 中文镜像
Sign inSign up
Watch966
Star102.4k
Fork61.8k
Tag: flutter
Switch branches/tags
Branches
Tags
K / Flutter Dart ffi 踩坑记录(各种报错).md
移动浏览 Clone
加载中...
到移动设备上浏览
128 lines 18.05 KB
First commit on 4 Nov 2020

    找不到文件

    报错:[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Invalid argument(s): Failed to load dynamic library (126)

    找不到路径,最好先使用 resolve 转换一下字符串,这样报错的时候也知道从哪里开始算根目录。

    import 'dart:io';
    import 'dart:ffi';
    
    final String dylibPath = Platform.script.resolve('./the-path/your-lib.dll').toFilePath();
    final DynamicLibrary dylib = DynamicLibrary.open(dylibPath);
    

    类型转换错误

    报错:lib/main.dart(19,31): error G733AAF94: Expected type 'NativeFunction<Function(String)>' to be a valid and instantiated subtype of 'NativeType'. [*\flutter\flutter_assemble.vcxproj]

    函数是先转成函数指针,再转成函数(下面两种方式)。另外传递字符串也要转成指针。

    // `Utf8` 指针转换依赖 ffi 包
    import 'package:ffi/ffi.dart';
    
    // 方式 1
    final funcPointer = dylib.lookup<NativeFunction<Function()>>('my_c_func');
    final myDartFunc = funcPointer.asFunction<Function()>();
    myDartFunc();
    
    // 方式 2(带一个整型参数),`lookupFunction<>` 里
    // 第一个对应 C 函数,整形用 Int32 声明,第二个对应 Dart 函数,用 int 声明。
    final myDartFunc = dylib.lookupFunction<Function(Int32), Function(int)>('my_c_func');
    myDartFunc(1);
    
    // 字符串转换,如果用 Function(String) 则报错。
    final myDartFunc = dylib.lookupFunction<Function(Pointer<Utf8>), Function(Pointer<Utf8>)>('my_c_func');
    myDartFunc(Utf8.toUtf8('The argv string.'));
    

    Porvider 和 setState() 错误

    报错:flutter: Another exception was thrown: setState() or markNeedsBuild() called during build.

    flutter: ══╡ EXCEPTION CAUGHT BY FOUNDATION LIBRARY ╞════════════════════════════════════════════════════════
    flutter: The following assertion was thrown while dispatching notifications for YourModel:
    flutter: setState() or markNeedsBuild() called during build.
    flutter: This _InheritedProviderScope<YourModel> widget cannot be marked as needing to build because
    flutter: the framework is already in the process of building widgets.  A widget can be marked as needing to
    flutter: be built during the build phase only if one of its ancestors is currently building. This exception
    flutter: is allowed because the framework builds parent widgets before children, which means a dirty
    flutter: descendant will always be built. Otherwise, the framework might not visit this widget during this
    flutter: build phase.
    flutter: The widget on which setState() or markNeedsBuild() was called was:
    flutter:   _InheritedProviderScope<YourModel>
    flutter: The widget which was currently being built when the offending call was made was:
    flutter:   TextFormField
    flutter:
    flutter: When the exception was thrown, this was the stack:
    flutter: #0      Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:4318:11)
    flutter: #1      Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:4333:6)
    flutter: #2      _InheritedProviderScopeElement.markNeedsNotifyDependents (package:provider/src/inherited_provider.dart:491:5)
    flutter: #3      ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:243:25)
    flutter: #4      YourModel.title= (package:lifelog_client/module/directory/edit/model.dart:27:5)
    flutter: #5      _FormTop.build.<anonymous closure>.<anonymous closure> (package:lifelog_client/module/directory/edit/form.dart:35:29)
    flutter: #6      FormFieldState._validate (package:flutter/src/widgets/form.dart:468:37)
    flutter: #7      FormFieldState.build (package:flutter/src/widgets/form.dart:518:13)
    flutter: #8      StatefulElement.build (package:flutter/src/widgets/framework.dart:4792:27)
    flutter: #9      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4675:15)
    flutter: #10     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4847:11)
    flutter: #11     Element.rebuild (package:flutter/src/widgets/framework.dart:4369:5)
    flutter: #12     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2777:33)
    flutter: #13     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:894:21)
    flutter: #14     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:320:5)
    flutter: #15     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1117:15)
    flutter: #16     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1055:9)
    flutter: #17     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:971:5)
    flutter: #21     _invoke (dart:ui/hooks.dart:157:10)
    flutter: #22     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:252:5)
    flutter: #23     _drawFrame (dart:ui/hooks.dart:120:31)
    flutter: (elided 3 frames from dart:async)
    flutter:
    flutter: The YourModel sending notification was:
    flutter:   Instance of 'YourModel'
    flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════
    flutter: Another exception was thrown: setState() or markNeedsBuild() called during build.
    

    这是在 Widget 重新 build() 完成之前调用了 setState(),在 Modelsetter 里调用 notifyListeners() 的地方套个延迟就可以了:

    Future.delayed(Duration(milliseconds: 500)).then((_) {
        notifyListeners();
    });
    

    析构错误

    [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: A YourModel was used after being disposed.
    Once you have called dispose() on a YourModel, it can no longer be used.
    #0      ChangeNotifier._debugAssertNotDisposed.<anonymous closure> (package:flutter/src/foundation/change_notifier.dart:117:9)
    #1      ChangeNotifier._debugAssertNotDisposed (package:flutter/src/foundation/change_notifier.dart:123:6)
    #2      ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:234:12)
    #3      YourModel._notify.<anonymous closure> (package:lifelog_client/module/directory/edit/model.dart:14:7)
    #4      _rootRunUnary (dart:async/zone.dart:1198:47)
    #5      _CustomZone.runUnary (dart:async/zone.dart:1100:19)
    #6      _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
    #7      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
    #8      Future._propagateToListeners (dart:async/future_impl.dart:725:32)
    #9      Future._complete (dart:async/future_impl.dart:519:7)
    #10     new Future.delayed.<anonymous closure> (dart:async/future.dart:323:16)
    #11     _rootRun (dart:async/zone.dart:1182:47)
    #12     _CustomZone.run (dart:async/zone.dart:1093:19)
    #13     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
    #14     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
    #15     _rootRun (dart:async/zone.dart:1190:13)
    #16     _CustomZone.run (dart:async/zone.dart:1093:19)
    #17     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1021:23)
    #18     Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
    #19     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:397:19)
    #20     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:428:5)
    #21     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
    

    这是上一个执行延迟 notifyListeners() 的副作用,因为延时了,所以在 Widget 析构后调用了 setState(),解决办法是给 Model 自定义 dispose(),不执行通知。

    未知错误

    [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Unimplemented handling of missing static target
    #0      _rootRunUnary (dart:async/zone.dart:1198:47)
    #1      _CustomZone.runUnary (dart:async/zone.dart:1100:19)
    #2      _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
    #3      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
    #4      Future._propagateToListeners (dart:async/future_impl.dart:725:32)
    #5      Future._complete (dart:async/future_impl.dart:519:7)
    #6      new Future.delayed.<anonymous closure> (dart:async/future.dart:323:16)
    #7      _rootRun (dart:async/zone.dart:1182:47)
    #8      _CustomZone.run (dart:async/zone.dart:1093:19)
    #9      _CustomZone.runGuarded (dart:async/zone.dart:997:7)
    #10     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
    #11     _rootRun (dart:async/zone.dart:1190:13)
    #12     _CustomZone.run (dart:async/zone.dart:1093:19)
    #13     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1021:23)
    #14     Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
    #15     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:397:19)
    #16     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:428:5)
    #17     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
    

    重新 run 一下就好了,不知道是什么问题,等待复现。