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引擎函数返回零的主要内容,如果未能解决你的问题,请参考以下文章