您的位置:首页 > 编程语言 > MATLAB

matlab tips

2016-02-26 14:11 274 查看


Matlab高阶应用——matlab工程程序转成C,并在VC2010环境下编译运行(codesgen)

参考:http://www.chinadmd.com/file/xtvatuzuiwscixvszrupaoct_4.html

Matlab程序转成C,并在VC2010环境下编译运行

前提:VC2010是32位的,所以对应的Matlab程序也应该要安装32位的;本人电脑64位,之前安装了64位的Matlab,无法使用VC2010编译器,后来再装了个32位的。

1.Matlab程序写法及转成C代码参见Matlab帮助文档:命令codegen

运行完codegen myFunctionname 后,Matlab会将用户定义的函数转换成一系列C语言代码,代码在Matlab工作目录下的codegen文件夹下。

2. 介绍转换代码功能;

Matlab在使用codegen生成C语言代码的同时,编译生成相应的.mex文件;以test.m函数转换成C语言代码为例。执行完“codegen test”后,会生成test.c; test_api.c; test_data.c;

test_initialize.c; test_mex.c; test_terminate.c,以及与之对应的头文件;同时生成test_mex.mex文件。熟悉matlab与C混合编程的朋友知道,执行codegen命令同时生成的.mex文件实质是编译这些C文件生成的;根据.mex文件名,可知程序的函数入口在test_mex.c文件中。

在文件test_mex.c文件中,找到程序入口函数void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])。其中nlhs为输出参数个数;plhs为输出参数对应的指针;nrhs和prhs为对应的输入参数信息。寻着函数调用关系深入,可以发现:

先调用test_initialize()函数对参数变量初始话;进而调用test_api()函数,在test_api函数中调用test()函数,即功能函数,执行完成后,调用test_terminate()函数结束。

3. Matlab转C部分小结及使用:

Matlab本身功能就很强大了,效率也很高,尤其是在矩阵运算方面;将Matlab函数转成C的主要目的是为了提高运算效率;用户可以将“循环”、“积分”等耗时的运算写成一个函数,利用codegen将该部分转成C函数文件,同时生成.mex,通过这样处理之后,通过调研.mex文件,可以几何级的提高运算效率。基于转换成的C文件,根据第2部分的介绍,用户可以找到C文件中相应需要调整修改的参数,直接修改保存,运行同一目录下的test_mex.bat批处理文件,将根据修改后的C文件生成新的.mex文件。

根据上面的介绍,对应一般的使用已经足够,下面介绍VC环境下编译转换成的C文件。

1. 配置VC编译器:

VC2010中新建win32控制台程序;将Matlab工程转换成的所有.c和.h的文件拷贝到VC工程目录中;填加到工程中;配置工程属性。选中工程名“右键”-“属性”;

在系统配置中C/C++下,添加include和references目录: (如图1所示)

图1. 在系统配置中C/C++下,添加include和references目录

Include: **\Program Files(x86)\MATLAB\R2011b\extern\include

**\Program Files(x86)\MATLAB\R2011b\extern\include\win32

References: **\Program Files(x86)\MATLAB\R2011b\extern\lib\win32\microsoft

在Linker\Input中,添加Additional Dependencies,即lib文件: (如图2所示)

图2. 添加lib文件
<
4000
p style="margin-top:0px;margin-bottom:0px;padding-top:0px;padding-bottom:0px;font-size:13px;color:rgb(51,51,51);font-family:'Lucida Grande', Helvetica, Arial;line-height:19.5px;text-indent:26px;">
(注)需要具体哪些lib文件,可先编译,缺什么找什么。Lib文件查找目录在References:**\Program Files(x86)\MATLAB\R2011b\extern\lib\win32\microsoft目录下;如编译报错说error LNK2019: unresolved external symbol _mexPrintf referenced in function _MainFunc;参见References目录下的lib文件,根据提示“_mexPrintf”,说明可能是libmex.lib文件。在Additional

Dependencies中添加之后,不报错说明就是缺少该lib文件,报错说明缺少的可能是别的。经过这样多次,最终顺利找到所有lib文件。

注意,在编译寻找缺失的lib文件前,需要将mexFunction注释掉,换成Main(),并添加mexFunction函数输入的初始定义,如图3所示:

图3. 修改相应代码

Lib文件配置成功后,编译将不会出错,但是会报错找不到各种动态链接库(.DLL)。

2.寻找缺失的.DLL文件:

对于简单的问题,缺失的.DLL基本都在*:\Program Files (x86)\MATLAB\R2011b\bin\win32目录下;

(请容许这里我多说两句,因为走向胜利的道路实在太坎坷了,不过这个过程确实很有意义) 最开始我的处理方式是编译运行程序,报错(缺少***.DLL),然后在目录下寻找,复制到我的工程文件目录下;当复制完所有的DLL之后,程序报错0xc000007b error "The application was unable to start correctly 0xc000007b";网上各种建议,最后采纳的提议为:采用VC自带的

dumpbin.exe(C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin),查是否因为32位和64位的.DLL混合调用造成的;运行dumpbin.exe的时候报错缺少“mspdb80.dll”后来再网上找到解决,修改环境变量path,详细见(http://blog.csdn.net/yaneng/article/details/5415822)解决

dumpbin.exe问题后,“开始”-“运行”-cmd 到doc界面,cd ..到程序目录,dumpbin /Header test.exe,查看test.exe的信息。后来发现没用。接着下载dependency walker小程序

(http://www.dependencywalker.com/),解压运行,打开要检查的.exe程序;将查出你缺少了那些DLL,我发现我的程序缺少的DLL太多了,

后来无赖,将matlab\bin目录下的所有DLL复制到了工作文件中,问题成功解决。

3. 报新的DLL缺失

完成上一步工作后,对于大部分程序都没有问题了,但我的工程比较庞大,里面涉及一些看上去无关紧要的程序段,出现地址指针的报错,我直接将其注释掉了,结果证明确实是无关紧要的,(如图4所示)

图4. 注释掉部分报错信息

但是还是出现新的错误,程序break到图5中的位置,报错信息缺少refblas.DLL。Matlab的bin目录下没有该DLL,电脑上其他位置也没有,从别的朋友那里Matlab2008的bin目录下找到该DLL,拷贝过来报错,后来在网上找到该DLL(),添加进工程目录,问题成功解决。

图5. 中断位置degmm32,缺失refblas.DLL

4. 至此,成功实现将Matlab中codegen生成的C语言文件在VC2010环境下编译运行成功。(花了两天解决该问题,三小时整理这些东西,希望对您有用,欢迎讨论)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  matlab