C中的Matlab引擎函数返回零

Posted

技术标签:

【中文标题】C中的Matlab引擎函数返回零【英文标题】:Matlab engine function in C returns zero 【发布时间】:2018-07-20 19:27:05 【问题描述】:

我想知道是否有人可以帮助我理解 C 语言中 Matlab 引擎的语法。我是 C 语言的初学者,正在尝试使用 Matlab 引擎在 C 语言中调用自定义 Matlab 函数。我所做的研究包括阅读 Matlab API 的文档、观看 Mathworks 的讲座视频、研究 Stack Overflow、阅读 Matlab 中的示例 eng.c 文件和 Google。

我想出了这段代码,它可以编译但输出返回零。输入数组也不返回数组,而是返回一个 int。我找不到关于如何构建 C 脚本的全面演练视频

    接受一个向量 将其输入 Matlab 函数并 返回输出。

文档非常清楚地解释了创建数组,但我找不到详细说明将数组读取到 Matlab 中然后获取输出的信息。

下面,请查看包含 cmets 的代码,了解我理解的每个代码部分的作用。示例函数add_up 只是在数组上调用sum 函数。任何帮助都会很棒,因为我不知道为什么返回零。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "engine.h"
#define BUFSIZE 256

int main() 

    //Open call to matlab engine
    Engine *ep;

    //Use this conjunction with define BUFSIZe 256 to create double
    //extData is a variable to read external data
    //Number in brackets refer to size
    //We are using double in this case and create the external data using initialization
    double extData[10]=1.0,4.0,7.0,2.0,5.0,8.0,3.0,6.0,9.0,10.0;

    //Next step is to make a pointer of type mxArray 
    //These are pointers to an array of any size or type
    mxArray *pVarNum;
    double *outp;

    //After we make a matrix for the double data initialized above
    //Initialized to 0
    pVarNum=mxCreateDoubleMatrix(1,10,mxREAL);

    //Our array needs to be assigned a variable name for Matlab
    //Workspace
    //const char *myDouble = "T";

    //Our matlab matrix is initialized to zero. We need to use
    //The C memcpy function to get the data from extData to
    //Get the array data using the pointer to pVarNum
    //Use mxGetPr, a mxGet function
    memcpy((void *)(mxGetPr(pVarNum)), (void *)extData,sizeof(extData));

    //Place the variable T into the Matlab workspace
    engPutVariable(ep,"T",pVarNum);

    //Evalute test function
    engEvalString(ep, "out=T+1");

    //Make a pointer to the matlab variable
    outp=engGetVariable(ep,"out");
    //Now make a pointer to the C variable
    printf("%d\n",outp);

    printf("Done!\n");
    mxDestroyArray(pVarNum);

    engClose(ep);

    return EXIT_SUCCESS;


【问题讨论】:

【参考方案1】:

engGetVariable 函数返回 mxArray*,而不是 double*

double *outp;
/* ... */
outp = engGetVariable(ep, "out");
printf("%d\n", outp);

这应该是:

mxArray *out;
double *outp;
int ii;
/* ... */
out = engGetVariable(ep, "out");
outp = mxGetPr(out);
for (ii = 0; ii < 9; ii++) 
   printf("%f, ", outp[ii]);

printf("%f\n", outp[9]);

还要注意printf 中的%d 格式化程序会打印一个int,您需要使用%f 作为双精度数。

【讨论】:

感谢您的回复,感谢您提供的信息。我按照建议修改了代码,如果我写 printf("%f",output),它现在将打印 0。但是,如果我尝试以任何方式访问 outp 的元素,它就会说存在分段错误,我查找它以表明指针内存访问存在问题。我猜这在某种程度上意味着 outp 不是双重的?您答案中的其他所有内容都是正确的,只是不会给我加倍的回报。 有趣...out 是 NULL 指针,还是 outp 是 NULL 指针? engGetVariable 如果“请求失败”返回 NULL(我猜这意味着请求的变量不存在?),如果 mxArray 没有真正的组件,或者不是数字,mxGetPr 将失败.据我所知,这些都没有发生在这段代码中。 感谢您的快速回复。我检查了输入 pVarNum 和输出。你说得对,out 有问题。它返回 Null,即使 pVarNum 不是 Null。我试图找到一种方法来访问 pVarNum 的元素以确保 memcpy 正常工作,即使它是从 api 手册中完全复制的。任何其他调试技巧也将不胜感激。 pVarNum 包含 extData 中的元素。因此,结论似乎是 Matlab 中的计算存在问题,因此它返回 Null。我不知道为什么会这样,因为我只是在示例中为数组的每个数字加一。 @Lee:检查engPutVariable的返回值(应该返回“成功返回0,出错返回1”)。如果 engEvalString 导致 MATLAB 内部出现错误,它不会告诉您(尽管在您的情况下它确实不会失败,只要存在 T,如果 engPutVariable 成功,它应该存在)。有关在这种情况下如何调试问题的一些想法,请参阅 here。【参考方案2】:

问题是 engputVariable 返回 1,因此 Matlab 引擎没有接收数组。我最终从 Matlab engdemo.c 中复制并粘贴了最上面的代码段(直到调用 engPutVariable),然后继续我的代码。工作代码文件的编码为 ASCII。我认为关键部分是使用 Null 字符串打开 Matlab 的初始调用,尽管我将这段确切的代码放在非工作脚本中,它并没有导致 engPutVariable 工作。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "engine.h"
#define  BUFSIZE 256

int main()


    Engine *ep;
    mxArray *T = NULL, *outp = NULL;
    double *out;
    int ii;
    char buffer[BUFSIZE+1];
    double time[10] =  0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 ;


    if (!(ep = engOpen(""))) 
        fprintf(stderr, "\nCan't start MATLAB engine\n");
        return EXIT_FAILURE;
    

    T = mxCreateDoubleMatrix(1, 10, mxREAL);
    memcpy((void *)mxGetPr(T), (void *)time, sizeof(time));

    engPutVariable(ep, "T", T);


    //Evalute test function. This is new

    engEvalString(ep, "D=add_up(T);");

    //Make a pointer to the matlab variable
    if((outp=engGetVariable(ep,"D"))==NULL)
        printf("Oops!");
    
    out= mxGetPr(outp);

    //Now make a pointer to the C variable
    for (ii=0; ii<10; ii++) 
        printf("%f\n", out[ii]);
    
    printf("%f\n",out[2]);

    printf("Done!\n");
    mxDestroyArray(T);
    mxDestroyArray(outp);
    engClose(ep);

    return EXIT_SUCCESS;


【讨论】:

以上是关于C中的Matlab引擎函数返回零的主要内容,如果未能解决你的问题,请参考以下文章

在C语言编程中,如何调用MATLAB的绘图功能?

matlab中的length表示啥?应该如何使用?

如何调试 Matlab 引擎 C API?

matlab中的norm( )是啥函数?

为啥matlab中的psnr函数为被柯西噪声破坏的图像返回负值?

MATLAB在数学建模中的应用