Flutter ngspice 插件

Flutter FFI 绑定 ngspice C 接口,实现一个 plugin 库:

  • 可通过 pubspec.yaml 引入
  • 上层提供 Dart API 接口
  • 底层通过 FFI 调用 C 代码

ngspice 是一个开源的电路仿真器,主要用于电子电路的分析和设计。

准备

创建项目

创建 Flutter FFI plugin 项目,

bash 复制代码
flutter create -t plugin_ffi --org cn.nebul --platforms ios,android,windows,linux,macos mozsim_ngspice

cd mozsim_ngspice/

flutter pub outdated
flutter pub upgrade --major-versions

flutter pub add ffi

获取共享库

获取 ngspice shared libs,可以找预编译库,不然就从源码编译。

1)预编译库

Windows 下载预编译库进 windows/ngspice-44.2_dll_64 目录。

bash 复制代码
$ tree windows -aF -L 2 --dirsfirst
windows
|-- ngspice-44.2_dll_64/
|                   `-- Spice64_dll/
|-- .gitignore
`-- CMakeLists.txt

2)从源码编译

bash 复制代码
# ngspice 44.2 Commit [e011d1] master
git clone -b master --depth 1 https://git.code.sf.net/p/ngspice/ngspice ngspice

# Windows
# - Building ngspice with MS Visual Studio 2022
#   - flex-bison/: https://sourceforge.net/projects/winflexbison/
#   - ngspice/visualc/sharedspice.sln: open as admin, run with ReleaseOpenMP x64

# Linux
./compile_linux_shared.sh

测试

Plugin 使用样例,

bash 复制代码
cd mozsim_ngspice/example/
flutter run

Dart 接口测试,

bash 复制代码
$ cd mozsim_ngspice/
$ dart test/mozsim_ngspice_test.dart
mozsim_ngspice_test ...
|Char| stdout Hello from ngspice
|Char| stdout Note: No compatibility mode selected!
|Char| stdout Circuit: * voltage divider netlist
|Stat| Prepare Deck
|Stat| Parse
|Char| stdout Doing analysis at TEMP = 27.000000 and TNOM = 27.000000
|Stat| Device Setup
|Char| stdout Using SPARSE 1.3 as Direct Linear Solver
|Stat| op
|Char| stdout No. of Data Rows : 1
|Char| stdout out = 6.666667e-01
|Char| stdout ngspice-44.2 done
|Char| stdout Note: 'quit' asks for resetting or detaching ngspice.dll.
|Exit| status 0 immediate false quit true
NgSpiceException: NgSpiceRequestType.command return error, ret=1
mozsim_ngspice_test done

C++ 接口测试,

powershell 复制代码
# Windows
> cd mozsim_ngspice/
> test\build\Debug\mozsim_ngspice_test.exe
mozsim_ngspice_test ...
|Char| stderr Warning: can't find the initialization file spinit.
|Char| stdout ******
|Char| stdout ** ngspice-44.2 shared library
|Char| stdout ** Creation Date: Jan 11 2025   14:16:40
|Char| stdout ******
|Char| stdout Hello from ngspice
|Char| stdout Note: No compatibility mode selected!
|Char| stdout Note: No compatibility mode selected!
|Char| stdout Circuit: * voltage divider netlist
|Stat| Prepare Deck
|Stat| Parse
|Char| stdout Doing analysis at TEMP = 27.000000 and TNOM = 27.000000
|Stat| Device Setup
|Char| stdout Using SPARSE 1.3 as Direct Linear Solver
|Stat| op
|Char| stdout No. of Data Rows : 1
|Char| stdout out = 6.666667e-01

接口

Dart 接口重生成,

bash 复制代码
# https://pub.dev/packages/ffigen
dart run ffigen --config ffigen.yaml

Dart 接口使用样例,

dart 复制代码
import 'package:mozsim_ngspice/ngspice.dart';

void main(List<String> args) async {
  print('mozsim_ngspice_test ...');
  await _main();
  // await _main();
  print('mozsim_ngspice_test done');
}

Future<void> _main() async {
  NgSpice? ngspice;
  try {
    ngspice = await NgSpice.initByLib(
      NgSpice.libPath(NgSpice.libName, 'test/build/Debug/'),
    );

    ngspice.resp.listen(_handleResponses);

    await ngspice.sendCommand('echo Hello from ngspice');

    await ngspice.sendCircs([
      '* voltage divider netlist',
      'V1 in 0 1',
      'R1 in out 1k',
      'R2 out 0 2k',
      '.end',
    ]);

    await ngspice.sendCommands(['op', 'print out']);
    await ngspice.sendCommand('quit');
  } on NgSpiceException catch (e) {
    print(e);
  } catch (e) {
    print('Caught error: $e');
  } finally {
    await ngspice?.close();
  }
}

void _handleResponses(NgSpiceResponse resp) {
  if (resp.type == NgSpiceResponseType.print) {
    final res = resp.data as String;
    print('|Char| $res');
  } else if (resp.type == NgSpiceResponseType.stat) {
    final res = resp.data as String;
    print('|Stat| $res');
  } else if (resp.type == NgSpiceResponseType.exit) {
    final (status, immediate, quit) = resp.data as (int, bool, bool);
    print('|Exit| status $status immediate $immediate quit $quit');
  }
}

参考

相关推荐
看昭奚恤哭17 分钟前
Flutter 布局核心思想
开发语言·javascript·flutter
末代iOS程序员华仔1 小时前
iOS上架海外工具类应用合规指南:避免封号与下架风险
flutter·ios·swift
末代iOS程序员华仔3 小时前
Flutter 开发 iOS App 上架全流程与常见问题分析
flutter·ios
末代iOS程序员华仔3 小时前
Flutter开发iOS海外工具类应用上架合规指南与风险规避
flutter·ios
蜡台15 小时前
Flutter 环境搭建 Dart配置
flutter·dart
落叶飘飘s1 天前
餐饮服务与软件创新的融合:解析海底捞 APP 的 Flutter 鸿蒙开发之路
flutter·华为·harmonyos
起司喵喵1 天前
Flutter-MacOS桌面OS系统|flutter.+window_manager客户端OS模板
flutter·macos·策略模式
Wuxiaoming1352 天前
flutter app的logo和splash logo尺寸
flutter
GitLqr2 天前
深入理解 Flutter 架构:从 Widget 到 GPU 像素的全链路解析
flutter·面试·dart
SoaringHeart2 天前
Flutter进阶|最佳实践:组件内阴影实现
前端·flutter