本帖最后由 Adel 于 2019-8-7 20:18 编辑
需要用VS调用MATLAB做数据拟合。
我已经实现了简单的VS2015调用MATLAB2018b的C和C++简单程序,见我上一篇分享帖子。其中实现的是VS调用MATLAB画图函数plot画图。
然而,现在我需要调用MATLAB中自己定义的函数(此函数还稍微有点点复杂,需要调用MATLAB的其他库函数),程序编译无误,但运行却报错指针地址读取失败(思考应该是函数调用失败)。我甚至将自己的函数写成一句一句的,每句都是MATLAB的基本语言或者库函数,还是报错内存错误。
然而调用简单的库函数是可以正确运行的。
请教高手,怎样解决?还是因为,VS调用MATLAB引擎运行MATLAB函数是有限制的,也就是我这个问题无解呢???
程序文件也粘贴在这里吧(附件虽然上传了代码文件(改后缀才能上传,都懂的——但是也不一定能看明文哦))——
TypeDefine.h
#ifndef __TYPEDEFINE_H__
#define __TYPEDEFINE_H__
#include
typedef int BOOL;
#define TRUE 1
#define FALSE 0
#endif
CruveFitting.h
#ifndef __CRUVE_FITTING_H__
#define __CRUVE_FITTING_H__
#include
#include"TypeDefine.h"
extern int CruveFitting(double inputX[],
double inputY[],
int cruveType,
BOOL isPiecewise,
int PiecewisePoint,
int firstPowerNo,
int secondPowerNo,
double relatedcoefficientR,
int parNo,
double Par[],
double concentrationVal,
double odVal,
int errorInfo);
#endif
CruveFitting.c
#include
#include
#include
#include
#include"CruveFitting.h"
#include"TypeDefine.h"
int CruveFitting(double inputX[],
double inputY[],
int cruveType,
BOOL isPiecewise,
int PiecewisePoint,
int firstPowerNo,
int secondPowerNo,
double relatedcoefficientR,
int parNo,
double Par[],
double concentrationVal,
double odVal,
int errorInfo)
{
int dataNum = 5;
int ret = 0;
Engine* eg = NULL;
if (!(eg = engOpen(NULL)))
{
printf("Open matlab enging fail!");
return 0;
}
engSetVisible(eg, true);
mxArray *X = mxCreateDoubleMatrix(1, dataNum, mxREAL); // 创建matlab存储数据的指针
mxArray *Y = mxCreateDoubleMatrix(1, dataNum, mxREAL);
memcpy(mxGetPr(X), inputX, dataNum * sizeof(double)); // 数据复制
memcpy(mxGetPr(Y), inputY, dataNum * sizeof(double));
if ((ret = engPutVariable(eg, "X", X)) != 0) // 把数据传递到matlab工作空间,并命名为X
printf("X:engPutVariable error:%d\n", ret);
if ((ret = engPutVariable(eg, "Y", Y)) != 0)
printf("Y:engPutVariable error:%d\n", ret);
//engEvalString(eg, "plot(x,y,'r')");// 运行绘图命令
//getchar();
mxArray *a, *b, *c; // matlab变量的指针
a = mxCreateDoubleScalar(0);
b = mxCreateDoubleScalar(1);
c = mxCreateDoubleScalar(2);
//if ((ret = engPutVariable(eg, "a", a)) != 0) //把数据传递到matlab工作空间,并命名为X
// printf("a:engPutVariable error:%d\n", ret);
//if ((ret = engPutVariable(eg, "b", b)) != 0)
// printf("b:engPutVariable error:%d\n", ret);
//if ((ret = engPutVariable(eg, "c", c)) != 0)
// printf("c:engPutVariable error:%d\n", ret);
// 自定义MATLAB的函数原型,其中调用了MATLAB库函数fittype和fit————————————————
/*%% Gompertz model 龚帕斯模型
function[a, b, c] = Gompertz_model_fitting(x, y)
p = fittype('a*exp(-exp(b-c*x) )', 'independent', 'x'); % y = ae ^ (-e ^ (b - cx))
f = fit(x, y, p);
a = f.a;
b = f.b;
c = f.c;
% plot(f, x, y);
end*/
//—————————————————————————————————————————————————
// 方式一:直接调用函数——————————————————————————————————————
// 结果会在下面memcpy(Par, mxGetPr(b), 1 * sizeof(double)); 句报错,应该是b指针为空,实际应该是函数调用失败(猜测)
//engEvalString(eg, "[a_calc, b_calc, c_calc] = Gompertz_model_fitting(X, Y)");
//—————————————————————————————————————————————————
// 方式二:将原自定义函数改为函数体执行语句,即只调用库函数及写MATLAB基本语句————————
// 依然和上面方式报一样的错误———————————
//engEvalString(eg, "p=fittype('a*exp(-exp(b-c*x))','independent','x');"); // 调用函数
//engEvalString(eg, "f=fit(X,Y,p);");
//engEvalString(eg, "a_calc = f.a;");
//engEvalString(eg, "b_calc = f.b;");
//engEvalString(eg, "c_calc = f.c;");
// ———————————————————————————————————————————————
// 这里是测试代码,直接调用一些MATLAB的库函数,最终正确运行————————————————
engEvalString(eg, "a_calc = sum(X);"); // 调用函数
engEvalString(eg, "b_calc = sum(Y);"); // 调用函数
engEvalString(eg, "c_calc = min(X);"); // 调用函数
//———————————————————————————————————————————————
a = engGetVariable(eg,"a_calc"); //从引擎获取矩阵
b = engGetVariable(eg, "b_calc"); //从引擎获取矩阵
c = engGetVariable(eg, "c_calc"); //从引擎获取矩阵
//memcpy(Par, (double*)mxGetPr(a_calc), 1 * sizeof(double)); // 本来计划是将参数传回到Par数组中
//memcpy(Par+1, (double*)mxGetPr(b_calc), 1 * sizeof(double));
//memcpy(Par+2, (double*)mxGetPr(c_calc), 1 * sizeof(double));
//Par = mxGetPr(a); // 测试代码,函数调用不成功,这句报错指针错误(内存错误)
//————————————————————————————————————————————————
// 在调函数时,运行到这句报错,错误见附图!
// ————————————————————————————————————————————————
memcpy(Par, mxGetPr(b), 1 * sizeof(double)); // 数据复制,
printf("b=%f\n", Par[0]);
// 测试代码
//double *p = mxGetPr(a_calc); //P指针指向矩阵的第一个元素
//printf("a=%f\n", p[0]);
//p = mxGetPr(b_calc); //P指针指向矩阵的第一个元素
//printf("b=%f\n", *p);
//p = mxGetPr(c_calc); //P指针指向矩阵的第一个元素
//printf("c=%f\n", *p);
if (eg)
{
mxDestroyArray(X);
mxDestroyArray(Y);
/*mxDestroyArray(a);
mxDestroyArray(b);
mxDestroyArray(c);*/
engClose(eg);
}
return 1;
}
main.c文件:
#include
#include
#include
#include
#include
#include"CruveFitting.h"
#include"TypeDefine.h"
int main()
{
int a = 0;
double x[5] = { 1, 1.5, 2, 2.5, 3 };
double y[5] = { 0.9, 1.7, 2.2, 2.6, 3 };
int cruveType = 1;
BOOL isPiecewise = 0;
int PiecewisePoint = 0;
int firstPowerNo = 0;
int secondPowerNo = 0;
double relatedcoefficientR = 0;
int parNo = 0;
double Par[3] = {0};
double concentrationVal = 0;
double odVal = 0;
int errorInfo = 0;
a = 2;
a = CruveFitting(x,
y,
cruveType,
isPiecewise,
PiecewisePoint,
firstPowerNo,
secondPowerNo,
relatedcoefficientR,
parNo,
Par,
concentrationVal,
odVal,
errorInfo);
printf("a=%d\n", a);
system("pause");
return 0;
}
1.png
(21.79 KB, 下载次数: 0)
2019-8-7 17:49 上传
2019-8-7 20:13 上传
点击文件名下载附件
4.51 KB, 下载次数: 2
2019-8-7 20:13 上传
点击文件名下载附件
406 Bytes, 下载次数: 1
2019-8-7 20:13 上传
点击文件名下载附件
803 Bytes, 下载次数: 2
2019-8-7 20:13 上传
点击文件名下载附件
141 Bytes, 下载次数: 1