matlab to c,m to c by MEX ~help

你给的程序不全,我看到过一篇文章,你可以借鉴一下,尽管你可能看不到这个帖子,呵呵。

发信人: fork (撒哈拉沙漠的沙), 信区: Matlab

标  题: 分析:解决m程序转化成cpp程序的编译问题【小波工工?

发信站: 哈工大紫丁香 (Sat Nov 29 21:32:06 2003), 站内信件

背景:有一个朋友想用小波变换对图像处理,利用现成的matlab的小波工具箱中的

程序。但是他导师要求将所有的matlab程序转化成c语言程序并在VC环境下编译。

其实,用matlab的程序转化为cpp文件并独立编译存在着很大的局限性。首先对于

很多已编译好的mex程序,虽然能够编译通过但通常会得到这个警告:

“the "XXX" function is only available in MEX mode. A run-time error

will occur if this code is executed in stand-alone mode.”这会引起一个

运行时错误,仔细检查会发现这样的mex文件是以dll形式存在,对应的m文件

只是一个幌子而已,m文件的存在仅仅是为了提供使用说明而已;即使你用到的

所有函数都是以m文件存在,有时候还是有问题,请看下面的程序:

%%%%%%%%%%%%%

function simon()

[X,map]=imread('simon.bmp');

x=X;

colormap(map);

x=double(x);

h=wavedecnd(x,2,'haar')

image(h{1});

%%%%%%%%%%%%%

该程序对simon.bmp做'haar'小波变换并显示第一块。

编译它:mcc -B sglCpp simon

运行编译后自动生成的simon.exe,发生错误:

“Exception!  File: handler.cpp, Line: 73

Variables are not supported by EVAL in compiled code.”

这段话表示函数"eval"不支持cpp编译,但是我们并没有显式的调用过这个函数

啊,那么肯定是在我们调用的其他函数中间接的调用了这个函数。于是打开

wavedecnd函数一个一个的检查所有它直接或间接调用过的函数,最后在

wavemngr.m中找到了对eval的三次调用:

“eval(['load ' bin_file ' -mat'],'err = 1;');”

如何来解决这个问题呢?mathworks给出了答案,参见:

http://www.mathworks.com/support/tech-notes/1100/1103.shtml

我选择了用“try catch”结构替换eval的间接调用:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%          eval(['load ' bin_file ' -mat'],'err = 1;');

try

load(bin_file,' -mat');

catch

err=1;

end

if err

err = 0;

%              eval(['load ' bin_ini_file ' -mat'],'err = 1;');

try

load(bin_ini_file,' -mat');

catch

err=1;

end

.......................................

%        eval(['save ' bin_file ' Wavelets_Info'],'err = 1;');

try

save(bin_file,' Wavelets_Info');

catch

err=1;

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

完成后,再一次编译:mcc -B sglCpp simon

运行程序,又出错:

“Exception!  File: handler.cpp, Line: 73

Reference to unknown function 'dbwavf' from FEVAL in stand-alone mode.”

意思是在feval中调用了未知函数“dbwavf”,于是找到在wfilters.m中有这样

一处调用:

“F = feval(fname,wname);”

而fname来自于该文件中的一句:

“[wtype,fname] = wavemngr('fields',wname,'type','file');”

追查!打开wavemngr.m看到了这样的语句:

“files = ...

{...

'dbwavf';

'dbwavf';

'symwavf';

'coifwavf';

'biorwavf';

'rbiowavf';

'meyer';

'dmey.mat';

'gauswavf';

'mexihat';

'morlet'

'cgauwavf';

'shanwavf';

'fbspwavf';

'cmorwavf'

};

于是解决的方法也就出来了,分析出错的原因在于文件中用feval间接的调用

了函数“dbwavf”,feval只是将它作字符串而不是文件名处理而之前的代码

中又没有显式的声明过该函数,因而编译器也就不知道还需要在生成的cpp代

码中加上对该函数的声明了,也不会额外的将dbwavf.m转化成cpp文件,解决

的办法有两个:

1,直接用“F = dbwavf(wname)”来替代“F = feval(fname,wname);”

再编译,运行,没问题了:)

2,读者一定发现第一个办法中问题了,如果是调用的symwavf,或者morlet

或者任何别的函数呢?那么这个方法就降低原程序的灵活性,解决的方法

(呵呵,想到这个方法实在需要些灵感!)就是在wfilters.m中该调用

“F = feval(fname,wname);”之前对所有有可能要调用到的函数做一次

伪声明(之所以叫伪声明是因为matlab中似乎没有声明一说,而这么做的

实质等同于c语言中的声明),即在“F = feval(fname,wname);”之前

加上一句:“dbwavf('haar');”

现在成了:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

dbwavf('haar');

if wtype==1                % orth. wavelet

if ~isempty(mat_f)

F = eval(wname);

else

F = feval(fname,wname);

%F=dbwavf(wname);

end

..................................

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

注意,我只加了一句:“dbwavf('haar');”,因为我知道它只会调用

这一个函数,如果它要调用多个函数,只要依样画葫芦就行了。

编译,运行,ok了:)

剩下的事情就是将生成的cpp文件和hpp文件加入到VC中的工程里,修改相应

的编译和连接参数,编译出一个独立的exe程序了。

本帖最后由 yangzhijie1488 于 2009-1-15 14:03 编辑]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值