https://www.tongyuan.cc/docs/sysplorer/2026b/Help/DevelopingModels/index.html#/Doc/DevelopingModels/AdvancedModels/ModelDebug/WindowsExternalFcnDebug.html#%E8%83%8C%E6%99%AF
使用 MWORKS 内置的外部函数调试功能(最推荐)
第一阶段:代码编写与编译(VS 端)
根据你的实际需求,选择隐式调用或显式调用。对于大多数 Sysplorer 扩展场景,推荐使用隐式调用(更简单,由系统自动管理)。
方案 A:隐式调用(推荐,简单直接)
编写头文件 (
.h):声明你的函数(如extern "C" __declspec(dllexport) int add(int a, int b);)。编写源文件 (
.cpp):实现该函数。VS 项目配置:
- 配置类型:动态库 (.dll)
- C/C++ -> 常规 -> 调试信息格式:设为
程序数据库 (/Zi)。 - 链接器 -> 调试 -> 生成调试信息:设为
是 (/DEBUG)。 - C/C++ -> 优化:设为
已禁用 (/Od)(调试期必须)。
点击生成:VS 会在
x64\Debug目录下生成.dll、.lib、.pdb。
方案 B:显式调用(灵活,支持容错)
- 仅编写 DLL 源文件:正常导出函数(
__declspec(dllexport))。 - 编写 C 封装层 (
CallDll.c):- 在
Initialize中调用LoadLibrary和GetProcAddress。 - 在
DoStep中通过函数指针调用。 - 在
Terminate中调用FreeLibrary。
- 在
- 编译:同样在 Debug 模式下生成
.dll和.pdb(此方案不需要.lib)。
第二阶段:部署与配置(Sysplorer 端)
不管你用哪种方案,Sysplorer 最终只认Demo(仿真的目录)目录下的文件。
同步部署文件:
- 打开你的 VS 输出目录(
C:\MyVSCode\...\x64\Debug)。 - 将最新的
.dll和.pdb(如果是隐式调用,加上.lib)复制并覆盖到你的 Sysplorer 工作目录(C:\Users\TR\Documents\MWORKS\ElectricalValve\Demo)。 - 注意:DLL 和 PDB 必须是同一次编译生成的,且修改时间戳一致。
- 打开你的 VS 输出目录(
Modelica 注解配置:
隐式调用:在 Modelica 代码的
annotation中配置Include、IncludeDirectory、Library、LibraryDirectory。显式调用:只需配置
Include指向你的 C 封装层,不需要配置Library。
环境清理:
如果之前仿真报错,建议进入
C:\Users\TR\Documents\MWORKS\Simulation目录,手动删除与当前模型相关的缓存文件夹(如System_Demo-1),防止旧版本 DLL 干扰。
第三阶段:VS 附加调试
这是容易出错的地方,请严格按此步骤执行:
让进程跑起来:在 Sysplorer 中点击“仿真”,让
MWSolver.exe在后台启动。附加到进程:回到 VS,点击菜单栏“调试” -> “附加到进程”,找到
MWSolver.exe,确保“附加到”选择的是“本机代码 (Native)”,点击附加。验证符号加载:打开 VS 的“调试” -> “窗口” -> “模块”,找到你的 DLL 模块(如
2026_10_23_Dll1.dll),确保“符号状态”显示为“已加载符号”。设置断点:在你的源码(如
Mydll.cpp的int c = a + b;)行打上断点。解决“源代码与原始版本不同”:
- 如果断点变成空心圆,且提示源码不一致,千万别直接勾选忽略。
- 正确的做法是:停止仿真,关闭 Sysplorer。回到 VS 重新“清理”并“重新生成”项目。重新将同批次生成的
.dll和.pdb复制到 Demo 目录。再次执行 1-4 步。
💡 排错方法
- 如果报错“无法定位程序输入点”或“找不到 xxx.dll”:检查你用的是不是隐式调用,但是忘了把
.lib放到对应目录,或者运行时找不到.dll。换成显式调用(LoadLibrary)可以优雅地捕获这个错误。 - 如果断点打死不进,但程序没报错:
- 去“模块”窗口看看你的 DLL 有没有加载符号。
- 去“Demo”目录右键看看 DLL 和 PDB 的修改时间是不是最新的。
- 检查 Sysplorer 的“仿真设置”里,是不是指定了其他的编译目录。
- 如果不弹 MessageBox:说明函数根本没被调用,或者调用的是旧版缓存(去 Simulation 目录清理缓存),或者断点位置不对(一定要打在函数体内部)。
总结口诀:改代码 -> 重新生成 -> 拷 DLL+PDB -> 清仿真缓存 -> 跑仿真 -> 附加进程 -> 下断点。只要保证DLL 与 PDB 绝对匹配,你的调试就能畅通无阻。