EXPORT_API intReadXXXDat(void* p, constchar* folder, int* pts){ if (!p || !folder || !pts) return0; auto proc = static_cast<CXXXProcessor*>(p); bool ok = proc->ReadXXXDat(folder); *pts = ok ? static_cast<int>(proc->m_vdpX.size()) : 0; return ok; }
EXPORT_API intGetPointCount(void* p){ return p ? static_cast<int>(static_cast<CXXXProcessor*>(p)->m_vdpX.size()) : 0; }
EXPORT_API intCopyX_mm(void* p, double* out, int max){ if (!p || !out || max <= 0) return0; auto proc = static_cast<CXXXProcessor*>(p); int n = std::min<int>(proc->m_vdpX.size(), max); for (int i = 0; i < n; ++i) out[i] = proc->m_vdpX[i] * 1000.0; return n; } EXPORT_API intCopyPower(void* p, double* o, int m){ returncopyVector(static_cast<CXXXProcessor*>(p), o, m, [](CXXXProcessor* q)->const std::vector<double>&{return q->PowerOut; }); } EXPORT_API intCopyGain(void* p, double* o, int m){ returncopyVector(static_cast<CXXXProcessor*>(p), o, m, [](CXXXProcessor* q)->const std::vector<double>&{return q->Gain; }); } EXPORT_API intCopyEff(void* p, double* o, int m){ returncopyVector(static_cast<CXXXProcessor*>(p), o, m, [](CXXXProcessor* q)->const std::vector<double>&{return q->Eff; }); } }
EXPORT_API intReadXXXDat(void* p, constchar* folder, int* pts){ if (!p || !folder || !pts) return0; auto proc = static_cast<CXXXProcessor*>(p); bool ok = proc->ReadXXXDat(folder); *pts = ok ? static_cast<int>(proc->m_vdpX.size()) : 0; return ok; }
调用 CXXXProcessor::ReadXXXDat(folder) 加载文件夹中的数据。
加载成功后将数据点数写入 pts。
m_vdpX 是轴向坐标数组。
GetPointCount
1 2 3
EXPORT_API intGetPointCount(void* p){ return p ? static_cast<int>(static_cast<CXXXProcessor*>(p)->m_vdpX.size()) : 0; }
返回总的数据点数(坐标数量)。
CopyX_mm
1 2 3 4 5 6 7
EXPORT_API intCopyX_mm(void* p, double* out, int max){ if (!p || !out || max <= 0) return0; auto proc = static_cast<CXXXProcessor*>(p); int n = std::min<int>(proc->m_vdpX.size(), max); for (int i = 0; i < n; ++i) out[i] = proc->m_vdpX[i] * 1000.0; return n; }
将轴向坐标 m_vdpX(单位:米)转换为毫米(乘以 1000)并复制到 out 缓冲区。
CopyPower, CopyGain, CopyEff
1 2 3 4
EXPORT_API intCopyPower(void* p, double* o, int m){ returncopyVector(static_cast<CXXXProcessor*>(p), o, m, [](CXXXProcessor* q)->const std::vector<double>&{return q->PowerOut; }); }
通过 copyVector 模板复制 PowerOut 数据。
1 2 3 4
EXPORT_API intCopyGain(void* p, double* o, int m){ returncopyVector(static_cast<CXXXProcessor*>(p), o, m, [](CXXXProcessor* q)->const std::vector<double>&{return q->Gain; }); }
复制增益(Gain)数据。
1 2 3 4
EXPORT_API intCopyEff(void* p, double* o, int m){ returncopyVector(static_cast<CXXXProcessor*>(p), o, m, [](CXXXProcessor* q)->const std::vector<double>&{return q->Eff; }); }
if ~libisloaded('XXXBridgeDLL') loadlibrary(dll,hdr); end
p = calllib('XXXBridgeDLL','CreateProcessor'); nPt = libpointer('int32Ptr',0); assert(calllib('XXXBridgeDLL','ReadXXXDat',p,dir,nPt)==1,'读取失败'); N = nPt.Value;
这段 MATLAB 代码演示了如何通过调用 C++ 动态链接库 XXXBridgeDLL.dll 来读取 XXX 仿真数据,并绘制输出功率、增益和效率随轴向位置变化的曲线
1. 加载 DLL 与设置路径
1 2 3 4 5 6 7
dll = 'H:\Matlab\bin\XXXBridgeDLL.dll'; hdr = 'H:\Matlab\bin\XXXBridgeDLL.h'; dir = 'C:\Users\pc\Desktop\XXX';
if ~libisloaded('XXXBridgeDLL') loadlibrary(dll,hdr); end
设置 DLL 文件路径、头文件路径和数据文件夹路径。
如果 DLL 尚未加载,则调用 loadlibrary 加载 DLL 并注册其接口函数。
2. 创建处理器并读取数据
1 2 3 4
p = calllib('XXXBridgeDLL','CreateProcessor'); nPt = libpointer('int32Ptr',0); assert(calllib('XXXBridgeDLL','ReadXXXDat',p,dir,nPt)==1,'读取失败'); N = nPt.Value;
%— ① Rising-edge → 启动 EXE ————————— if u == 1 && prevU == 0 && exeState == 0 [ok, procObj, pid, exeState] = launchExe(exePath, paramPath); if ok fprintf('[XXX] PID=%d 已启动\n', pid); else exeState = -1; % 启动失败 end end
%— ② 运行中 → 轮询进程是否退出 ————— if exeState == 1 [exeState, pid] = pollProcessExitStatus(procObj, pid); if exeState == 2 || exeState == -1 stopSimulation(block); end end
%— ③ 输出 & 保存 ————————— block.OutputPort(1).Data = exeState; block.Dwork(1).Data = u; block.Dwork(2).Data = exeState; block.Dwork(3).Data = pid; end
% ─── Terminate:处理进程退出 —── functionTerminate(~) persistent procObj if ~isempty(procObj) try terminateProcess(procObj); catch % Ignore if the process has already been terminated end end end
% ─── helper:启动进程 ─── function[ok, proc, pid, exeState] = launchExe(exePath, paramPath) ok = false; proc = []; pid = 0; exeState = 0; try if exist(exePath, 'file') ~= 2 warning('[XXX] EXE 不存在: %s', exePath); return; end if exist(paramPath, 'dir') ~= 7 warning('[XXX] 参数路径不存在: %s', paramPath); return; end
argStr = ['1|1|' paramPath]; % 启动参数 proc = System.Diagnostics.Process(); info = proc.StartInfo; info.FileName = exePath; info.Arguments = argStr; info.UseShellExecute = false; info.CreateNoWindow = true; ok = proc.Start(); if ok pid = double(proc.Id); exeState = 1; % 运行中 end catch ME warning('[XXX] 启动 EXE 异常: %s', E.message); end end
% ─── helper:轮询进程退出状态 ─── function[exeState, pid] = pollProcessExitStatus(procObj, pid) finished = false; try procObj.Refresh(); finished = procObj.HasExited; if ~finished finished = procObj.WaitForExit(50); % 等待 50 ms end catch finished = ~isProcAlive(pid); end if finished exitC = getExitCodeSafe(procObj); exeState = (exitC == 0) * 2 + (exitC ~= 0) * (-1); pid = 0; else exeState = 1; % Running end end
% ─── helper:检查 PID 是否仍存活 ─── functionalive = isProcAlive(pid) alive = false; if pid <= 0, return; end try pchk = System.Diagnostics.Process.GetProcessById(pid); alive = ~pchk.HasExited; catch % Process not found end end
% ─── helper:读取 ExitCode ─── functioncode = getExitCodeSafe(procObj) code = -1; try code = procObj.ExitCode; catch, end end
% ─── helper:终止进程 ─── functionterminateProcess(procObj) if ~procObj.HasExited procObj.Kill(); end procObj.Dispose(); end
% ─── helper:停止仿真 ─── functionstopSimulation(block) set_param(bdroot(block.BlockHandle), 'SimulationCommand', 'stop'); end