Dart通过FFI调用libwebp.dll实现WebP编码时应用崩溃的问题排查求助
Dart通过FFI调用libwebp.dll实现WebP编码时应用崩溃的问题排查求助
各位大佬好,我现在卡在了用Dart通过FFI调用libwebp.dll做WebP编码的问题上——调用编码函数时整个应用直接崩溃,连异常都抓不到,实在没头绪了,来求助大家!
背景和代码情况
我从jacklicn的libwebp仓库编译出了libwebp.dll,然后写了下面的FFI调用代码:
import 'dart:ffi'; import 'dart:io'; import 'package:ffi/ffi.dart'; import 'package:flutter/foundation.dart'; typedef NativeEncodeFunc = Uint64 Function( Pointer<Uint8> rgb, Int32 width, Int32 height, Int32 stride, Float quality_factor, Pointer<Pointer<Uint8>> output, ); typedef DartEncodeFunc = int Function( Pointer<Uint8> rgb, int width, int height, int stride, double quality_factor, Pointer<Pointer<Uint8>> output, ); typedef NativeFreeFunc = Void Function(Pointer<Uint8>); typedef DartFreeFunc = void Function(Pointer<Uint8>); class WebPFFI { late final DynamicLibrary _lib; late final DartEncodeFunc _encode; late final DartFreeFunc _free; WebPFFI() { final path = _getLibraryPath(); try { _lib = DynamicLibrary.open(path); // 加了符号检查,没抛出异常 if (_lib.providesSymbol('WebPEncodeRGB') == false) { throw Exception('Symbol WebPEncodeRGB not found in library'); } _encode = _lib .lookup<NativeFunction<NativeEncodeFunc>>('WebPEncodeRGB') .asFunction(); _free = _lib .lookup<NativeFunction<NativeFreeFunc>>('WebPFree') .asFunction(); } catch (e) { throw Exception('Failed to load WebP library ($path): $e'); } } Uint8List encode(Uint8List rgb, int width, int height, int quality) { // 基础参数检查 if (width <= 0 || height <= 0) { throw ArgumentError('Invalid dimensions: $width x $height'); } if (quality < 0 || quality > 100) { throw ArgumentError('Quality must be between 0 and 100'); } final rgbPtr = malloc<Uint8>(rgb.length); rgbPtr.asTypedList(rgb.length).setAll(0, rgb); final outputPtr = calloc<Pointer<Uint8>>(); try { // 就是这一行直接导致应用崩溃,没有任何异常输出 final resultSize = _encode( rgbPtr, width, height, width * 3, // RGB格式的stride quality.toDouble(), outputPtr, ); if (resultSize == 0) { throw Exception('WebP encoding failed'); } final result = outputPtr.value.asTypedList(resultSize); return Uint8List.fromList(result); } finally { if (outputPtr.value != nullptr) { _free(outputPtr.value); } calloc.free(outputPtr); malloc.free(rgbPtr); } } String _getLibraryPath() { if (Platform.isWindows) return 'windows/libwebp.dll'; if (Platform.isLinux) return 'linux/libwebp.so'; if (Platform.isMacOS) return 'macos/libwebp.dylib'; if (Platform.isAndroid) return 'android/libwebp.so'; // 修正了之前的路径错误 if (Platform.isIOS) return 'ios/libwebp.dylib'; // 修正了之前的路径错误 if (kIsWeb) throw UnsupportedError('Web平台不支持这种FFI调用方式'); throw UnsupportedError('当前平台不支持加载WebP库'); } }
已经做的排查
- 用
dumpbin /EXPORTS libwebp.dll | findstr "WebPEncodeRGB"检查了dll的导出符号,确认存在:30 1D 00033A60 WebPEncodeRGB 31 1E 00033AA0 WebPEncodeRGBA - 加了符号检查代码,确认能找到
WebPEncodeRGB符号,没有抛出异常; - 确认
_lib和_encode都不为null,初始化流程没问题。
疑问和求助点
- 明明符号能找到、函数指针也成功拿到了,为什么一调用就直接崩溃?
- 我的FFI函数签名有没有问题?比如返回值类型、参数类型的映射是否和libwebp的C接口匹配?
- 有没有可能是内存操作的问题?比如输入的RGB数据长度不对导致内存访问越界?
- 正确的WebP编码流程应该是怎样的,我有没有遗漏什么关键步骤?
麻烦各位大佬帮忙看看问题出在哪,谢谢了!
内容来源于stack exchange
相关产品推荐
相关产品推荐

