C语言如何直接调用MATLAB函数?

99ANYc3cd6
预计阅读时长 19 分钟
位置: 首页 C语言 正文

核心概念:MATLAB Engine API

MATLAB Engine API 是 MATLAB 提供的一组接口(C/C++ 和 Fortran),允许你的外部程序(如 C/C++ 应用)启动一个 MATLAB 进程,并与其进行交互,你可以:

c语言调用matlab函数
(图片来源网络,侵删)
  1. 启动 MATLAB:从 C 代码中启动一个 MATLAB 会话。
  2. 执行 MATLAB 命令:发送单个 MATLAB 命令(如 a = 1 + 2;)并执行。
  3. 调用 M 函数:调用你预先编写好的 .m 文件函数。
  4. 传递数据:将 C/C++ 中的数组、矩阵等数据传递给 MATLAB,并将 MATLAB 计算的结果传回 C/C++。
  5. 管理会话:获取输出、检查错误、以及最终关闭 MATLAB 引擎。

重要前提:这种方式需要目标机器上安装了 MATLAB,你的 C 程序本质上是一个 MATLAB 的“客户端”,它依赖于一个正在运行的 MATLAB“服务器”。


详细步骤:C 调用 MATLAB 函数

假设我们要调用一个名为 my_adder.m 的 MATLAB 函数。

第 1 步:编写 MATLAB 函数

创建一个简单的 MATLAB 函数 my_adder.m,它接收两个矩阵作为输入,返回它们的和。

my_adder.m

c语言调用matlab函数
(图片来源网络,侵删)
function [result] = my_adder(A, B)
% This function adds two matrices element-wise.
% It includes a simple check for dimensions.
    if ~isequal(size(A), size(B))
        error('Input matrices must have the same dimensions.');
    end
    result = A + B;
end

将这个文件保存在 MATLAB 的搜索路径中,或者保存在你接下来将要运行的 C 程序的同一目录下。

第 2 步:配置 C/C++ 开发环境

这是最关键也最容易出错的一步,你需要告诉你的 C/C++ 编译器去哪里找 MATLAB 的头文件和库文件。

以 Windows + Visual Studio 为例:

  1. 找到 MATLAB 安装路径:假设你的 MATLAB 安装在 C:\Program Files\MATLAB\R2025a
  2. 包含头文件目录
    • 在 Visual Studio 中,右键你的项目 -> 属性
    • 配置属性 -> C/C++ -> 常规 -> 附加包含目录
    • 添加路径:C:\Program Files\MATLAB\R2025a\extern\include
  3. 添加库文件目录
    • 配置属性 -> 链接器 -> 常规 -> 附加库目录
    • 添加路径:C:\Program Files\MATLAB\R2025a\extern\lib\win64\microsoft
    • 注意:这里的 win64microsoft 会根据你的操作系统和编译器而变化,Linux 下是 glnxa64,macOS 下是 maci64
  4. 链接库文件
    • 配置属性 -> 链接器 -> 输入 -> 附加依赖项
    • 添加库文件名:libmx.lib, libmat.lib, libeng.lib
    • libeng.lib 是 Engine API 的核心库,必须包含。

对于 Linux (GCC) 或 macOS (Clang),通常使用 mex 命令来编译,它会自动处理这些路径和库链接。

c语言调用matlab函数
(图片来源网络,侵删)

第 3 步:编写 C/C++ 代码

下面是一个完整的 C 语言示例,它启动 MATLAB,调用 my_adder 函数,并传递数据。

call_matlab.c

#include <stdio.h>
#include <stdlib.h>
// 包含 MATLAB Engine API 的头文件
#include "engine.h"
int main() {
    // 1. 声明一个 MATLAB 引擎指针
    Engine *ep;
    // 2. 启动 MATLAB 引擎
    // ep 为 NULL,表示启动失败
    if (!(ep = engOpen(NULL))) {
        fprintf(stderr, "\nCan't start MATLAB engine.\n");
        return EXIT_FAILURE;
    }
    // 3. 准备输入数据
    // 创建两个 2x2 的 double 矩阵
    mxArray *A = mxCreateDoubleMatrix(2, 2, mxREAL);
    mxArray *B = mxCreateDoubleMatrix(2, 2, mxREAL);
    // 获取矩阵数据指针并赋值
    double *A_data = (double *)mxGetPr(A);
    double *B_data = (double *)mxGetPr(B);
    A_data[0] = 1.0; A_data[1] = 2.0;
    A_data[2] = 3.0; A_data[3] = 4.0;
    B_data[0] = 5.0; B_data[1] = 6.0;
    B_data[2] = 7.0; B_data[3] = 8.0;
    // 4. 将输入数据放入 MATLAB 工作区
    engPutVariable(ep, "A_in", A);
    engPutVariable(ep, "B_in", B);
    // 5. 调用 MATLAB 函数
    // engEvalString 执行一个完整的 MATLAB 命令字符串
    // 这里我们调用 my_adder 函数,并将结果存入 C_in
    engEvalString(ep, "C_in = my_adder(A_in, B_in);");
    // 6. 从 MATLAB 工作区获取结果
    mxArray *C_out = engGetVariable(ep, "C_in");
    if (C_out == NULL) {
        fprintf(stderr, "\nFailed to get result from MATLAB.\n");
        engClose(ep);
        return EXIT_FAILURE;
    }
    // 7. 处理结果
    double *C_data = (double *)mxGetPr(C_out);
    printf("Result from MATLAB function my_adder:\n");
    printf("[%.1f, %.1f]\n", C_data[0], C_data[1]);
    printf("[%.1f, %.1f]\n", C_data[2], C_data[3]);
    // 8. 清理和关闭
    // 释放 mxArray 内存
    mxDestroyArray(A);
    mxDestroyArray(B);
    mxDestroyArray(C_out);
    // 关闭 MATLAB 引擎
    engClose(ep);
    return EXIT_SUCCESS;
}

第 4 步:编译和运行

在 Visual Studio 中:

  1. 确保你已经正确配置了包含目录和库目录。
  2. 直接点击“生成” -> “生成解决方案”。
  3. 运行生成的可执行文件。

在命令行 (GCC on Linux/macOS):

# 假设 mex 命令在 PATH 中
# mex 会自动找到 MATLAB 的路径
gcc call_matlab.c -o call_matlab -lmx -lmat -lmex -leng
  • -lmx, -lmat, -lmex, -leng 是链接时需要的库。

运行程序后,你应该会看到 MATLAB 启动一个后台进程,并打印出计算结果:

Result from MATLAB function my_adder:
[6.0, 8.0]
[10.0, 12.0]

重要替代方案:MATLAB Coder

如果你遇到以下情况,MATLAB Coder 是一个更好的选择:

  • 部署目标没有安装 MATLAB:你希望将算法集成到一个手机 App、嵌入式设备或服务器上。
  • 追求性能:C/C++ 代码通常比通过 Engine API 调用有更低的性能开销。
  • 简化依赖:你的最终产品不应该依赖于一个庞大的 MATLAB 运行时环境。

工作流程:

  1. 编写 MATLAB 函数:你的 MATLAB 代码必须是“可编译的”,这意味着它不能使用动态脚本、eval、某些特定的图形函数等,MATLAB Coder 会有详细的检查。

  2. 使用 MATLAB Coder:在 MATLAB 命令行中使用 codegen 命令。

    % 假设你的函数是 my_adder.m
    % 定义输入类型
    A = coder.typeof(0, [2 2], 1); % 2x2 的 double 矩阵
    B = coder.typeof(0, [2 2], 1);
    % 生成 C/C++ 代码
    codegen my_adder -args {A B} -o my_adder_lib
  3. 获得 C/C++ 代码codegen 会在当前目录下生成一个 my_adder_lib 文件夹,里面包含 .h 头文件和 .c 源文件。

  4. 集成到你的 C 项目:你不再需要 libeng.lib 等库,你只需要将生成的 .h.c 文件包含/链接到你的 C 项目中,然后像调用普通 C 函数一样调用它。

优点

  • 无 MATLAB 依赖:生成的代码是独立的。
  • 高性能:直接编译为机器码,避免了进程间通信的开销。
  • 易于部署:最终的发布包更小、更简洁。

缺点

  • 限制较多:并非所有 MATLAB 语法和函数都支持。
  • 额外工具:需要购买或使用 MATLAB Coder 工具箱。

总结对比

特性 MATLAB Engine API MATLAB Coder
原理 启动 MATLAB 进程,通过通信接口调用 将 MATLAB 代码直接编译成 C/C++ 代码
依赖 需要安装 MATLAB 不需要安装 MATLAB
性能 较低(有进程间通信开销) (直接执行机器码)
适用场景 快速原型验证、交互式计算、调试 部署到最终产品、追求性能、嵌入式系统
代码灵活性 高,可以执行任何 MATLAB 命令 受限,代码必须是“可编译的”
部署复杂度 低(只需配置链接器),但依赖大 高(需要集成生成的代码),但依赖小

如何选择?

  • 如果你的目标是在已有 MATLAB 环境下进行快速开发、测试或原型验证,并且不关心最终部署时的依赖,使用 Engine API
  • 如果你的目标是将算法作为产品的一部分发布,或者需要在没有 MATLAB 的环境中运行,并且对性能有要求,强烈推荐使用 MATLAB Coder
-- 展开阅读全文 --
头像
Linux C语言开发环境如何快速搭建?
« 上一篇 昨天
dede如何判断用户是否已登录?
下一篇 » 昨天

相关文章

取消
微信二维码
支付宝二维码

目录[+]