分析:解决m程序转化成cpp程序的编译问题

发信人: 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程序了。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值