c++ - 在 WebAssembly 中使用 ngspice 库
问题描述
在使用 ngspice 作为 webassembly (wasm) 项目中的库时,我需要一些帮助。
我安装了 emsdk 和最新版本的 emcc (1.39.20) 并下载了 ngspice 版本 32 的源代码。
令我最惊讶的是,我能够按照本指南将 ngspice 编译为 wasm 目标:
emconfigure ./configure --with-ngshared --disable-debug
emmake make
(我必须通过添加到这一行来修补configure
一点以通过检查.out.js a.out.wasm
:)
# The possible output files:
ac_files="a.out a.out.js a.out.wasm conftest.exe conftest a.exe a_out.exe b.out conftest.*"
这产生了一个libngspice.so.0.0.0
我试图从 C++ 代码链接到的文件。然而,失败了duplicate symbol: main
。所以它似乎 libngspice.so.0.0.0
包含一个函数,如果我正确理解配置脚本main
的目的,它不应该存在。--with-ngshared
于是我手动把ngspice的main
函数去掉了,用上面的方法重新编译。main.c
这次我可以成功编译我自己的项目,链接到 ngspice。但是,当我调用时ngSpice_Init
,我收到以下运行时错误:
stderr Note: can't find init file.
exception thrown: RuntimeError: unreachable executed,@http://localhost:8001/sim.js line 1802 > WebAssembly.instantiate:wasm-function[67]:0x24e9
@http://localhost:8001/sim.js line 1802 > WebAssembly.instantiate:wasm-function[88]:0x423b
...
最小的可重复步骤:
- 如上编译ngspice
- 编译下面的代码使用
em++ -o sim.html sim.cpp lib/libngspice.so
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sharedspice.h"
using namespace std;
int recieve_char(char * str, int id, void* p){
printf("recieved %s\n", str);
}
int recieve_stat(char* status, int id, void* p){
printf("status: %s\n", status);
}
int ngexit(int status, bool unload, bool exit, int id, void* p){
printf("exit: %d\n", status);
}
int recieve_data(vecvaluesall* data, int numstructs, int id, void* p){
printf("data recieved: %f\n", data->vecsa[0]->creal);
}
int recieve_init_data(vecinfoall* data, int id, void* p){
printf("init data recieved from: %d\n", id);
}
int ngrunning(bool running, int id, void* p){
if(running){
printf("ng is running\n");
}else{
printf("ng is not running\n");
}
}
int main(){
ngSpice_Init(&recieve_char, &recieve_stat, &ngexit,
&recieve_data, &recieve_init_data, &ngrunning, (void*)NULL);
char** circarray = (char**)malloc(sizeof(char*) * 7);
circarray[0] = strdup("test array");
circarray[1] = strdup("V1 1 0 1");
circarray[2] = strdup("R1 1 2 1");
circarray[3] = strdup("C1 2 0 1 ic=0");
circarray[4] = strdup(".tran 10u 3 uic");
circarray[5] = strdup(".end");
circarray[6] = NULL;
ngSpice_Circ(circarray);
ngSpice_Command("run");
return 0;
}
那么有人可以帮我正确地将ngspice库编译为wasm目标吗?
(在有人问之前,是的,我已经看过这个问题,但没有多大帮助)
解决方案
在对 ngspice 源进行多次更改后,我能够编译库和示例代码。可以在此处找到有关如何将 ngspice 编译为 wasm 的补丁和指南。
(导致我的问题中显示的错误的问题是示例代码,没有从签名应该返回的函数返回任何内容int
。这在 wasm 中是不允许的。)
推荐阅读
- racket - 如何将每个元素添加到列表中?
- python - 根据现有列中的值创建 Pandas DF 列
- r - 包 ecodist 中的功能 MRM 的尺寸不正确错误
- swift - Swift 从 CoreData 转换为 CoreLocation - 有一些问题
- visual-studio - 是否可以使用 PyCharm 以外的 IDE 远程调试 AWS Glue 脚本?
- flutter - 是否可以根据 ThemeData 中的 lightTheme 或 darkTheme 更改图标?飘飘然
- python - 在连接到 VPN 客户端 AWS 的同时连接到 SFTP
- sql - 为什么 WHERE 子句从结果中删除空值?
- python - pythons os.path.join 在绝对路径之前删除所有参数的用例是什么?
- c - 简单循环上的分段错误