You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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库');
  }
}

已经做的排查

  1. 用dumpbin /EXPORTS libwebp.dll | findstr "WebPEncodeRGB"检查了dll的导出符号,确认存在:
    30 1D 00033A60 WebPEncodeRGB
    31 1E 00033AA0 WebPEncodeRGBA
    
  2. 加了符号检查代码,确认能找到WebPEncodeRGB符号,没有抛出异常;
  3. 确认_lib和_encode都不为null,初始化流程没问题。

疑问和求助点

  • 明明符号能找到、函数指针也成功拿到了,为什么一调用就直接崩溃?
  • 我的FFI函数签名有没有问题?比如返回值类型、参数类型的映射是否和libwebp的C接口匹配?
  • 有没有可能是内存操作的问题?比如输入的RGB数据长度不对导致内存访问越界?
  • 正确的WebP编码流程应该是怎样的,我有没有遗漏什么关键步骤?

麻烦各位大佬帮忙看看问题出在哪,谢谢了!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 11:23:04