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

参考

相关推荐
GitLqr1 天前
玩转 Flutter 中的 Stack 与 Positioned:解决 UI 重叠问题的实战指南
flutter·面试·全栈
唔661 天前
flutter web iOS 在浏览器加载中文慢的问题
前端·flutter·ios
恋猫de小郭1 天前
Jetpack Compose 8 月版正式发布,核心模块 1.12
android·前端·flutter
梦想的颜色2 天前
AI 时代小白 VibeCoding 做 APP:UniApp(含 Uni‑X)、Flutter 与 React Native+Expo全维度技术选型对比指南
flutter·react native·app·uniapp·vibecoding·unippx·app产品
坚果的博客2 天前
Flutter-OH 3.44.9-dev 悄然上线|首个 OpenHarmony Canary 预览版上线
flutter
大龄秃头程序员2 天前
Flutter 动画随笔:业务里真正高频的几类控件
flutter
天空之城--2 天前
Android Flutter行业最新动态与实用参考(2026年8月第2周)
android·flutter
恋猫de小郭2 天前
Flutter 3.47 发布,快来看看有什么更新吧
android·前端·flutter
大龄秃头程序员3 天前
一次 Flutter 动画 Demo 的整理与复盘
flutter