看到各种mwException问题都没答案,现在将我自己遇到的问题与解决方案提供如下,希望能帮助和我遇到相同问题的筒子们。
问题描述:
用VS2010调用matlab生成的dll时出错,报mwException错误。
matlab代码如下:
%用PCA方法降低维数
%A:输入的样本矩阵;n,要降到的维数
%RESULT:输出的特征矩阵
function RESULT=PCA(A,n)
C = cov(A); %求协方差矩阵
[X,B] = eig(C); %求特征值矩阵B和特征向量矩阵X
D = diag(B); %提取B对角线元素,获得特征值向量
Dr = D; %初始特征值向量
sort(D,'descend'); %对D进行降序排序
t = 0; %记录要提取那个特征向量
RESULT = [];
for i = 1:n
t = find(Dr == D(i));
RESULT = [RESULT,X(:,t(1))];
end
end
VS2010中调用代码如下:
//功能:计算降维特征矩阵;
//输入:filename,输入数据文件名称;rfilename,输出数据文件名称;n,PCA降到的维数
//输出:rfilename中存储了降维特征矩阵;
void CalculateSpecialMatrix(char*filename,char *rfilename,int n)
{
float temp = 0; //为了转换存储设定的临时变量;
int nargout = 2; //定义输出参数的个数;
float a[200][440]; //存储样本中心数据;
FILE *fp = fopen(filename,"r");
FILE *fpr = fopen(rfilename,"w");
if( ! mclInitializeApplication(NULL,0) )
{
fprintf(stderr, "Could not initialize the application.\n");
exit(1);
}
// 初始化库;
if (!libpcaInitialize() )
{
fprintf(stderr,"Could not initialize the library.\n");
exit(1);
}
mwArray A(200,440,mxDOUBLE_CLASS); //中心阵;
mwArray RESULT(440,n,mxDOUBLE_CLASS); //结果特征矩阵;
mwArray myn(1,2,mxDOUBLE_CLASS);
TODO:这里添加代码;
if (fp == NULL)
{
AfxMessageBox("Open file wrong!");
return;
}
if (fpr == NULL)
{
AfxMessageBox("Open file wrong!");
return;
}
myn = (double)n;
fread(a,sizeof(float),200*440,fp); //读入数据;
for (int i = 0; i < 200; i++) //格式化处理;
{
for (int j = 0; j < 440; j++)
{
A(i+1,j+1)= (double)a[i][j];
}
}
PCA(nargout,RESULT,A, myn);
for (int i = 1; i <= 440; i++) //行;
{
for (int j = 1; j <= n; j++)//列;
{
temp = RESULT.Get(i,j);
fprintf(fpr,"%f ",temp);
}
fprintf(fpr,"\n");
}
// 关闭库和程序;
libpcaTerminate() ;
mclTerminateApplication() ;
}
出错位置:
PCA(nargout,RESULT,A, myn); //出错位置!!!!!!!!!!!!!!!!!!!!!!!
问题分析:
有人说,他自己的是因为fread、fwrite的缘故,尝试过,但是失败了。我相当不明白的是matlab函数调用出错和fread或fwrite有什么关系。我认为,既然matlab中调用不存在问题,而其他matlab函数用相同的调用方法也没有问题,那么,唯一可能出问题的地方就是参数不符合要求。在以上思想指导下,我重新观察了所有参数的值,发现类型全部正确,也不存在越界的问题。
在没有任何头绪的情况下,突然想到,我对参数nargout的理解还不是很透彻,是不是理解出问题了。之前,在网上看到说这个是参数个数,于是,想当然的认为是输入参数的个数,也没有问问自己为什么需要设置一个输入参数个数。。。懒了,我的错。
于是,我在matlab中打入了"help nargout",然后就发现了问题所在。nargout指定了输出参数的个数,也就是函数返回值的个数,和输入参数半毛钱关系都没。。大家也可以看到,我的PCA()只有一个返回值,而我的nargout赋初值为2!!!于是,改过之后,一切恢复正常。
结论:
mwException出错的一种情况是参数不正确,不仅仅类型不正确会出现问题,参数值有时也会造成错误。
经验教训:
在学习的过程中,所采取的学习资料一定要够权威,最好是官方文档。另外,学习,千万不能一知半解,如有什么地方不清楚,一定要搞到明白为止,否则,后患无穷。