You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:01:15