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

C调用Matlab编译DLL传递字符串参数时路径报错问题求解

问题背景

需要实现从C代码向Matlab函数传递字符串类型的文件名入参,Matlab端逻辑为根据传入的名称查找对应数据文件,加载文件内数据到矩阵。Matlab端函数代码如下:

function bus = new(casefile)
{
   A=loadcase(casefile);
% 对数据做额外处理后返回复数双精度矩阵
}

通过Matlab Compiler将该Matlab函数编译为DLL文件,编写C侧测试代码传递文件名参数调用,C代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "matrix.h"
#include "new.h"


int run_main(int argc, const char** argv)
{
    mxArray* casename;
    mxArray* sbus=NULL;

    sbus = mxCreateDoubleMatrix(9, 1, mxCOMPLEX);
    casename = mxCreateString("case9.m");

    if (!newInitialize()) 
    {
        fprintf(stderr, "Could not initialize the library.\n");
        return -2;
    }
    else
    {
        /* 调用库函数 */
        mlfnew(1, &sbus, casename);
        newTerminate();

        mxDestroyArray(casename);
       
    }
    mclTerminateApplication();
    return 0;
}



int main(int argc, const char** argv)
{
    
    if (!mclInitializeApplication(NULL, 0))
    {
        fprintf(stderr, "Could not initialize the application.\n");
        return -1;
    }
    return mclRunMain((mclMainFcnType)run_main, argc, argv);
}

程序运行时抛出如下报错:

loadcase: specified M file does not exist
loadcase: specified case not in MATLAB's search path

已完成的排查操作:

  • 尝试在传入的文件名字符串中加入完整目录绝对路径,报错未解决
  • 确认数据文件与Matlab函数位于同一目录,且该目录已添加至本地Matlab搜索路径

解决方案
  • 核心问题:动态依赖文件未被打包进编译产物
    Matlab Compiler编译DLL时,只会静态扫描代码中显式调用的函数和依赖,通过字符串参数动态加载的文件(比如loadcase读取的case9.m)不会被自动识别并打包进CTF归档包。编译后的程序运行在独立的MCR环境中,和你本地Matlab的搜索路径配置完全隔离,哪怕你本地已经把目录加进Matlab路径,MCR运行时也读不到这些文件。
    编译时必须手动将所有需要动态加载的case数据文件添加到编译配置的「Additional Files」列表中,确保文件被打入CTF包。
  • 修正Matlab端运行时路径逻辑
    CTF包在程序运行时会被解压到临时目录,和你本地源码存放路径无关,直接传本地绝对路径或者裸文件名都无法定位文件,需要在Matlab函数内适配编译后的运行环境:
    function bus = new(casefile)
        % 去除文件名后缀,loadcase不需要.m后缀
        casefile = erase(casefile, ".m");
        % 编译运行环境下自动配置路径
        if isdeployed
            addpath(ctfroot);
        end
        A = loadcase(casefile);
        % 后续数据处理、返回复数矩阵逻辑
    end
    
    注意:原Matlab函数用大括号包裹函数体属于语法错误,Matlab函数不需要大括号包裹代码块,直接在function声明后编写逻辑即可。
  • 修正C侧调用逻辑
    1. 创建字符串入参时不要带.m后缀,直接传入mxCreateString("case9")即可。
    2. 不需要提前调用mxCreateDoubleMatrix创建sbus,输出参数的mxArray由mlf接口自动分配内存,提前创建的矩阵会造成内存泄漏甚至参数传递错误,保持sbus = NULL初始化即可。
    3. 若调试时需要定位路径问题,可在初始化MCR后开启日志打印,直接查看运行时实际搜索的文件路径列表,避免传本地开发机的无效绝对路径。
  • 可选:C侧显式添加MCR搜索路径
    如果不把数据文件打进CTF包,而是放在C程序同级目录,可在调用newInitialize()后,通过MCR提供的接口将程序当前目录显式加入MCR搜索路径,MCR默认不会读取系统环境变量或程序当前工作目录。

内容的提问来源于stack exchange,提问作者S2022

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 10:06:33