最近由于项目需求,某项目的算法是基于MATLAB完成的,在短时间内需要去调用算法功能。因此,基于MATLAB生成DLL, C 调用的方式完成。
环境:MATLAB 2013a + VS2010 + win8.1 + 64位系统
一、MATLAB 编译环境设置
1. 安装,MATLAB安装时选择 force 32bit, 这样生成的dll在32位和64位的机器上都可以调用。
2. 装好MATLAB 2013后,打开软件,进行配置
1 >> mex -setup
2 Welcome to mex -setup. This utility will help you set up
3 a default compiler. For a list of supported compilers, see
4 http://www.mathworks.com/support/compilers/R2013a/win32.html
5 Please choose your compiler for building MEX-files:
6 Would you like mex to locate installed compilers [y]/n?y
7 Select a compiler:
8 [1] Lcc-win32 C 2.4.1 in D:\PROGRA~2\MATLAB\R2013a\sys\lcc
9 [2] Microsoft Visual C++ 2010 in D:\Program Files (x86)\Microsoft Visual Studio 10.0
10
11 [0] None
12
13 Compiler: 2
14
15 Please verify your choices:
16
17 Compiler: Microsoft Visual C++ 2010
18 Location: D:\Program Files (x86)\Microsoft Visual Studio 10.0
19
20 Are these correct [y]/n? y
21
22 ***************************************************************************
23 Warning: MEX-files generated using Microsoft Visual C++ 2010 require
24 that Microsoft Visual Studio 2010 run-time libraries be
25 available on the computer they are run on.
26 If you plan to redistribute your MEX-files to other MATLAB
27 users, be sure that they have the run-time libraries.
28 ***************************************************************************
29
30
31 Trying to update options file: C:\Users\robin\AppData\Roaming\MathWorks\MATLAB\R2013a\mexopts.bat
32 From template: D:\PROGRA~2\MATLAB\R2013a\bin\win32\mexopts\msvc100opts.bat
33
34 Done . . .
显示 Done 后执行下一步
1 >> mbuild -setup
2
3 Welcome to mbuild -setup. This utility will help you set up
4 a default compiler. For a list of supported compilers, see
5 http://www.mathworks.com/support/compilers/R2013a/win32.html
6
7 Please choose your compiler for building shared libraries or COM components:
8
9 Would you like mbuild to locate installed compilers [y]/n? y
10
11 Select a compiler:
12 [1] Microsoft Visual C++ 2010 in D:\Program Files (x86)\Microsoft Visual Studio 10.0
13
14 [0] None
15
16 Compiler: 1
17
18 Please verify your choices:
19
20 Compiler: Microsoft Visual C++ 2010
21 Location: D:\Program Files (x86)\Microsoft Visual Studio 10.0
22
23 Are these correct [y]/n? y
24
25 ****************************************************************************
26 Warning: Applications/components generated using Microsoft Visual C++
27 2010 require that the Microsoft Visual Studio 2010 run-time
28 libraries be available on the computer used for deployment.
29 To redistribute your applications/components, be sure that the
30 deployment machine has these run-time libraries.
31 ****************************************************************************
32
33
34 Trying to update options file: C:\Users\robin\AppData\Roaming\MathWorks\MATLAB\R2013a\compopts.bat
35 From template: D:\PROGRA~2\MATLAB\R2013a\bin\win32\mbuildopts\msvc100compp.bat
36
37 Done . . .
这样,MATLAB的Mex编译环境就配置好了。
二、MATLAB 代码编译dll
打开MATLAB源代码,找到最顶层的m文件,注意顶层必须为function方式。
例如,MATLAB的顶层函数为
文件 ship_track1.m
1 function finish_flag = ship_track1(input_x,input_y,num_ori)
为某目标检测算法,input_x ,input_y,和num_ori为输入的3个参数
那么编译的指令为
1 >> mcc -W cpplib:libship_track1 -T link:lib ship_track1.m -C
配置完成后会在MATLAB工程目录生成7个文件
1 libship_track1.cpp
2 libship_track1.ctf
3 libship_track1.dll
4 libship_track1.exp
5 libship_track1.exports
6 libship_track1.h
7 libship_track1.lib
当然我们需要用到的只有4个
1 libship_track1.ctf
2 libship_track1.dll
3 libship_track1.h
4 libship_track1.lib
三、VS2010 MFC 工程配置
1. 新建VS2010 MFC 工程
2. 将第二步MATLAB编译生成的4个文件拷贝入MFC工程目录下
将头文件 libship_track1.h 添加进工程
3. 项目属性设置
1)选择项目->项目属性->所有配置
C/C++ -> 常规->附加包含目录,找到MATLAB下的include目录
1 D:\Program Files (x86)\MATLAB\R2013a\extern\include
(根据MATLAB的安装路径确定)
2)链接器->常规->附加库目录
1 D:\Program Files (x86)\MATLAB\R2013a\extern\lib\win32\microsoft
3) 链接器->输入->附加依赖项
1 libship_track1.lib
2 libship_track2.lib
3 mclmcrrt.lib
4 libmx.lib
5 libmat.lib
6 mclmcr.lib
到此就配置完成。
四、MFC 调用DLL
1. 初始化
1 if(!libship_track1Initialize()) //初始化1通道
2 {
3 //MessageBox(_T("could not initialize the application"));
4 }
2. 传递参数
1 double _Data1_1[5] = {0}; //输入数组
2 double _Data1_2[5] = {0};
3 for(int i=0; i< chn1_num; i++)
4 {
5 _Data1_1[i] = Chan1_x[i];
6 _Data1_2[i] = Chan1_y[i];
7 }
8
9 mxArray* Data1_1 = mxCreateDoubleMatrix(1, 5,mxREAL); //创建1*5矩阵
10 memcpy(mxGetPr(Data1_1), (void*)_Data1_1,sizeof(_Data1_1)); //拷贝输入数据
11 mxArray* Data1_2 = mxCreateDoubleMatrix(1, 5,mxREAL); //创建1*5矩阵
12 memcpy(mxGetPr(Data1_2), (void*)_Data1_2,sizeof(_Data1_2)); //拷贝输入数据
13 double _Data1_3[1];
14 _Data1_3[0] = chn1_num;
15 mxArray* Data1_3 = mxCreateDoubleMatrix(1, 1,mxREAL); //创建1*1矩阵;
16 memcpy(mxGetPr(Data1_3), (void*)_Data1_3,sizeof(_Data1_3)); //拷贝输入数据
17 mxArray *input1[3] = {Data1_1,Data1_2,Data1_3}; //将矩阵x的指针作为输入参数传递进去
18 //mxArray *output[1]; //定义输出参数指针
19 mlxShip_track1(0,NULL, 3, input1);
mxArray是Matlab C 函数库的结构体,需要利用它来进行参数传递。
对于mlxShip_track1函数来说,其四个参数分别对应:
mlxShip_track1(输出参数个数、输出参数、输入参数个数、输入参数)