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

参考

相关推荐
恋猫de小郭2 小时前
Android Studio Panda 2 ,支持 AI 用 Vibe Coding 创建项目
android·前端·flutter
Gorit4 小时前
如何使用 Flutter 开发 HarmonyOS 应用
flutter·华为·harmonyos
孤影过客4 小时前
Flutter高性能任务管理APP开发实战代码解析
jvm·flutter·oracle
键盘鼓手苏苏16 小时前
Flutter 三方库 p2plib 的鸿蒙化适配指南 - 实现高性能的端到端(P2P)加密通讯、支持分布式节点发现与去中心化数据流传输实战
flutter·harmonyos·鸿蒙·openharmony
加农炮手Jinx16 小时前
Flutter for OpenHarmony:postgrest 直接访问 PostgreSQL 数据库的 RESTful 客户端(Supabase 核心驱动) 深度解析与鸿蒙适配指南
数据库·flutter·华为·postgresql·restful·harmonyos·鸿蒙
加农炮手Jinx16 小时前
Flutter 组件 heart 适配鸿蒙 HarmonyOS 实战:分布式心跳监控,构建全场景保活检测与链路哨兵架构
flutter·harmonyos·鸿蒙·openharmony
钛态16 小时前
Flutter 三方库 http_mock_adapter — 赋能鸿蒙应用开发的高效率网络接口 Mock 与自动化测试注入引擎(适配鸿蒙 HarmonyOS Next ohos)
android·网络协议·flutter·http·华为·中间件·harmonyos
王码码203516 小时前
Flutter for OpenHarmony:Flutter 三方库 algoliasearch 毫秒级云端搜索体验(云原生搜索引擎)
android·前端·git·flutter·搜索引擎·云原生·harmonyos
王码码203516 小时前
Flutter 三方库 dns_client 的鸿蒙化适配指南 - 告别 DNS 劫持、探索 DNS-over-HTTPS (DoH) 技术、构建安全的鸿蒙网络请求环境
flutter·harmonyos·鸿蒙·openharmony·dns_client