如何实现Matlab/Simulink与Visual Studio C++项目的实时数据交互?
解决Matlab/Simulink与C++实时数据交互的方案
针对你已经搞定C与外部服务器实时通信,现在需要打通Matlab/Simulink和C数据链路的场景,我整理了几个高实用性的方案,覆盖不同的实时性需求:
1. 原生MEX文件(最高实时性)
MEX是Matlab与C/C交互的官方原生方式,直接在Matlab进程内运行C代码,几乎没有进程间通信的开销,非常适合实时场景。
核心步骤:
- 编写一个MEX函数,接收Matlab传入的数组(比如
mxArray类型),直接提取内存指针传递给你的C++服务器通信模块 - 服务器返回的数据,通过MEX函数封装成
mxArray回传给Matlab - 在Simulink中,可以用MEX Function模块直接调用这个函数,作为数据输入/输出节点
极简示例(伪代码):
#include "mex.h" // 你的C++服务器通信函数,假设接收float数组,返回处理后的结果 float* send_to_server(float* data, int length, int* out_length) { // 调用已实现的通信逻辑 } void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // 从Matlab获取输入数据 float* in_data = (float*)mxGetData(prhs[0]); int in_len = mxGetNumberOfElements(prhs[0]); // 调用服务器通信 int out_len; float* out_data = send_to_server(in_data, in_len, &out_len); // 把结果返回给Matlab plhs[0] = mxCreateNumericMatrix(1, out_len, mxSINGLE_CLASS, mxREAL); float* matlab_out = (float*)mxGetData(plhs[0]); memcpy(matlab_out, out_data, out_len * sizeof(float)); // 记得释放内存 delete[] out_data; }
在Matlab里编译这个文件:
mex your_mex_function.cpp
之后直接调用result = your_mex_function(your_data);,Simulink里拖入MEX模块指定这个函数即可。
2. 共享内存(跨进程实时交互)
如果你的C程序是独立进程(而非嵌入Matlab),共享内存是低延迟的跨进程通信方案,适合Matlab和C程序并行运行的场景。
实现思路:
- C++端:创建共享内存区域,写入服务器返回的数据,或者读取Matlab写入的数据
- Matlab端:用
memorymap对象直接映射到共享内存区域,实现无拷贝读写
简单示例:
C++端(Windows平台):
#include <windows.h> int main() { // 创建共享内存 HANDLE hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, L"MySharedMemory"); float* pBuf = (float*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 4096); // 假设从服务器获取数据后写入共享内存 float server_data[100]; // ... 接收服务器数据到server_data ... memcpy(pBuf, server_data, 100 * sizeof(float)); // 记得关闭句柄 UnmapViewOfFile(pBuf); CloseHandle(hMapFile); return 0; }
Matlab端:
% 映射共享内存 m = memorymap('MySharedMemory', 'uint8', [1 4096], 'Writable', true); % 转换为float数组 server_data = typecast(m.Data, 'single'); % 处理数据...
3. 本地TCP/UDP套接字(兼容现有通信逻辑)
既然你已经实现了C与外部服务器的套接字通信,完全可以复用这套逻辑,在本地建立TCP/UDP连接,让Matlab和C通过本地端口交互。
优势:
- 逻辑和与外部服务器的通信一致,无需额外学习新API
- 支持Matlab和C++在不同机器(同一局域网)交互,扩展性强
Matlab端示例(TCP):
% 连接本地C++服务 t = tcpclient('localhost', 12345); % 发送数据到C++ write(t, your_matlab_data, 'single'); % 接收服务器返回的数据 received_data = read(t, 100, 'single'); % 关闭连接 close(t);
C++端:只需要在现有通信代码基础上,增加一个本地套接字服务端,接收Matlab的数据后转发给外部服务器,再把响应回传给Matlab即可。
Simulink专属优化
如果用Simulink做实时仿真,除了MEX模块,还可以:
- 使用S-Function Builder可视化生成MEX函数,无需手动写C++代码
- 开启快速仿真模式(Accelerator Mode),提升交互的实时性
- 用Data Store Memory模块配合MEX实现数据共享
实时性注意事项
- 尽量传递连续内存的数组(Matlab的原生数组都是连续的,C++直接用指针访问,避免拷贝)
- 减少数据传输的大小,只传递必要的字段,比如用结构体代替大矩阵
- 避免在交互线程中做耗时计算,把通信和计算逻辑分离
内容的提问来源于stack exchange,提问作者Hierend
相关产品推荐
相关产品推荐

