本文主要讨论第四种方法。另外随着Matlab 版本的升级, 原来的math library已经并入了Compiler 之中, 是否是mathworks 比较推崇DLL 的方式呢?
一.首先进行 Matlab编译环境的设置(环境为Matlab6.5&VC++6.0)
为了能够使用Matlab 的Complier 将*.m函数文件编译为动态链接库DLL,必须对Matlab的环境做出相应的配置。具体做法如下:
在Matlab 的Command Window 下输入命令mbuild –setup,并根据Matlab 的提示选择合适的编译器,笔者使用的是Microsoft Visual C++.过程如下: >> mbuild –setup
Please choose your compiler for building standalone MATLAB applications: Would you like mbuild to locate installed compilers [y]/n? Select a compiler:
[1] Lcc C version 2.4 in D:\\MATLAB6P5\\sys\\lcc
[2] Microsoft Visual C/C++ version 7.0 in C:\\Program Files\\Microsoft Visual Studio .NET [3] Microsoft Visual C/C++ version 6.0 in D:\\Microsoft Visual Studio [0] None
Compiler: 3 //这里填入3 Please verify your choices:
Compiler: Microsoft Visual C/C++ 6.0 Location: D:\\Microsoft Visual Studio Are these correct?([y]/n): //确认输入y //在Command Window 中输入命令 cd(prefdir);mccsavepath;
这是为了后面使用Matlab 在VC++ IDE 中的Add-in 作准备。然后输入命令mex – setup, 以类似的方法配置编译器。至此, Matlab 的配置完成。
可以参阅Matlab 的帮助MatlabCompiler\\Getting Started\\Installation and configuration 一节。
二.创建动态链接库( *.DLL)
创建动态链接库主要有两种方法: 一种是使用Matlab 为VC++ IDE提供的Add-in。这种方法比较简单,方便快捷,只要在VC++中创建工程的时候选择Matlab Project Wizard,并且在接下来的Step 1 中的Visual Matlab Application Type选择Shared M-DLL 就可以了。接下来就是添加*.m 文件, 进行编译了。另一种方法就是使用Matlab的mcc命令将*.m文件编译为动态链接库(*.DLL)。因为Add-in 也是调用Compiler 的命令mcc 进行编译工作的, 而且有时候这个Add-in 还会出现不能使用的情况,
因此这里主要讨论使用mcc 命令的方法。
这里我们使用命令 mcc–B csglsharedlib : youlibname function1 funcion2 „ 来创建我们所需要的动态链接库DLL文件。(mcc -t -h -L C -W lib : ppp -T link :lib myfunct.m) 其中
参数-B表示使用的是Bundle Files 作为参数,
csglsharedlib 是-B 的参数, 意思是生成使用Matlab 图形库的C 共享动态链接库, youlibname 是你想要生成的动态链接库DLL的文件名,
注意csglsharedlib 与youlibname之间有一个冒号“:”连接,
function1 为你想要加入到动态链接库DLL 中的函数名,如果有多个函数,各个函数名用空格隔开。 在我们的例子中,首先创建所需的Matlab函数文件myfun.m。 function y=myfun(timeend) t=0:0.001:timeend; y=sin(2*pi*50*t); plot(y);
然后使用命令 mcc -B csglsharedlib:mylib myfun 生成动态链接库DLL。Matlab 会生成一系列文件,其中mylib.h mylib.lib mylib.dll 以及相同目录下的bin\\ 下的FigureMenuBar.fig 和FigureToolBar.fig 是我们在以后所需要使用的。
三.在VC++中使用Matlab 生成的动态链接库( *.DLL)
为了能在VC++中使用上面生成的*.DLL,首先要对VC++的环境进行一些设置: ( 1) 设置Include 和Library 目录
在VC++ IDE 中选择Tools->Options->Directories。
在Show directoris for:中选择Include files, 添加如下两个目录: 在Show directoris for:中选择Library files, 添加如下两个目录: 这些操作只需要一次, VC++ IDE 就会自动记录。自动应用到每一个工程(Project)。 (2)工程(project)本身的一些设置 在VC++ IDE 中选择Project->Setting->C/C++ 在Category 中选择Code Generation, 在Use run-time library 中选择Multithreaded DLL。 在Category 中选择Precompiled Headers,选择Automatic use of precompiled headers, 并且在Through header 下面添加stdafx.h。 在Category 中选择Preprocessor , 在preprocessor definitions 中添加MSVC,MSWIND,IBMPC. 在VC++ IDE 中选择Project->Settings->Link 在Categories 中选择Input, 在Ignore libraries:中填入: msvcrt.lib。 ( 3) 为工程添加相应的文件 把刚才生成的mylib.h mylib.dll mylib.lib 和 接下来就可以使用刚才生成的动态链接库mylib.dll了。首先要在使用DLL 中函数的源文件中加上头文件mylib.h。在使用之前还需要对mylib.dll 进注册, 使用完毕之后需要对其进行释放。注册使用函数 mylibInitiallize();释放使用函数mylibTerminate()。函数名的规则就是youlibname+Initialize(Terminate). 这两函数在mylib.h 中可以找到。 mylibInitialize()不仅注册了刚才生成的mylib.dll, 同时它也注册了Matlab 本身的一些动态链接库( *.DLL); 同理mylibTerminate()不仅释放了刚才生成的mylib.dll, 同时它也释放了Matlab 本身的一些动态链接库( *.DLL)。因此在注册了mylib.dll 之后, 我们也可以使用Matlab 的数学库中的函数, 例如mlfabs(), mlfAssign()等等。 在使用mylib.dll 的时候, 存在着一个VC++和mylib.dll 中的函数之间数据交互的问题。由于mylib.dll 中的函数所接受的参数是mxArray 型数据。因此我们要使用Matlab 为我们提供的External Interfaces/ API 函数来创建mxArray 型数据,大量的API函数可以参见Matlab 的帮助文件Matlab\\External Interfaces/API Reference\\C MX-Functionsx小节。在进行调用的时候,我们使用的是m文件的文件名myfunct,而不是m文件中定义的myfun。可以在mylib.h 中看到。 下面就是一个实例 //包含头文件 #include “mylib.h” //注册动态链接库 mylibInitialize(); double x=0.04; //创建mxArray 型数据并对其赋值 mxArray *t; t=mxCreateDoubleMatrix(1,1,mxREAL); memcpy(mxGetPr(t),&x,sizeof(double)); //或者使用t=mxCreateDoubleScalar(x) //或者使用Matlab 数学库中的函数mlfAssign()等 //使用mylib.dll 中的函数 mlfMyfun(t); //销毁t, 释放内存 mxDestroyArray(t); //注销动态链接库 mylibTerminate(); 参数格式转换:应该指出,MATLAB所有计算都是基于一种名为mxArray的数据结构之上的,所有的浮点数、向量或者矩阵在MATLAB当中都是通过mxArray结构来进行存储和传递的。当然,MATLAB所提供的所有数学函数也都是基于这样一种数据结构进行计算的。所以,要使用MATLAB的生成代码,就必须将C语言当中常用的浮点数和整数转换成mxArray结构。可以利用MATLAB的函数 mxArray *mlfScalar(double v)和函数double *mxGetPr(mxArray *)来实现参数格式的转换。函数mlfScalar()将double型变量存入一个新建的mxArray结构中,并返回指针,而函数mxGetPr将mxArray结构保存的实数的实部取出。 一个实例: void CMatDlg::OnButton1() {//在matlab中定义的m文件:myfunct,其功能是完成两个数的相加操作。 CString str; UpdateData(true); pppInitialize(); //为了调用matlab中的函数,必须使用数组数据类型,并其后调用matlab函数将其转化为矩阵格式(matlab的基本数据类型是矩阵) static double x1[1]={1.0}; static double x2[1]={2.5}; double result; //调用matlab创建3个矩阵 mxArray *A=mclGetUninitializedArray(); mxArray *B=mclGetUninitializedArray(); mxArray *C=mclGetUninitializedArray(); //将C语言中的变量值赋给matlab中的矩阵 mlfAssign(&A,mlfDoubleMatrix(1,1,x1,NULL)); mlfAssign(&B,mlfDoubleMatrix(1,1,x2,NULL)); mlfAssign(&C,mlfMyfunct(A,B)); //将matlab中的矩阵的指针传递给C语言中的指向double的指针 double * md=mxGetPr(C); result=md[0]; //释放这些矩阵 mxDestroyArray(A); mxDestroyArray(B); mxDestroyArray(C); str.Format (\"It is : %f\ ::AfxMessageBox(str); } 相信看到里面的注释,我们就明白的差不多了。 VC编程以实现对matlab函数的调用,例如VC中我们实现两个double型的相加,则需要做上述的编程:首先定义两个数组并存入我们要进行函数操作的数据(也就是所谓的实参);然后将这两个数组转换为matlab可以识别的矩阵;然后调用m文件中自定义的函数,对矩阵进行操作;最后将结果再转回VC支持的数据格式: double * md=mxGetPr(C); result=md[0]; 至此,经matlab函数处理过的数据已经存入了VC中的result变量。 mlfAssign(&C,mlfMyfunct(A,B)); 4 程序的发布 在程序完成之后, 就可以进行打包发布了。需要注意的问题就是发布的时候除了生成的mylib.dll 和FigureMenuBar.fig、FigureToolBar.fig, 还需要加上Matlab 的一些动态链接库。这样发布的程序就可以完全脱离Matlab 的环境而独立运行了。如何得到这些动态链接库呢? 将 创建COM 组件,对这种不兼容性有了一定的改进,使得Matlab 和高级语言的混合编程变得越来越实用,越来越简单。 下载示例代码1 下载示例代码2 MATLAB广泛应用于线性代数、自动控制理论、数理统计、数字信号处理、时间序列分析、动态系统仿真等领域。因此假如在VC中对MATLAB进行调用将大大减少编程的工作量、保证程序的准确性,并且继续了VC++强大的功能,提高开发效率,本文将介绍了在VC中使用MATLAB函数库的具体步骤: 在VC中建立一个项目后: 1.设置: 添加路径: 在PRoject-settings-c/C++-category:-preprocessor-Additional include Directories:栏目中添加: D:\\MATLAB6P1\\EXTERN\\INCLUDE, D:\\MATLAB6P1\\EXTERN\\INCLUDE\\CPP, D:\\MATLAB6P1\\EXTERN\\LIB lib 在project-settings-c/C++-category:-preprocessor-preprocessor definitions: 栏目中添加: MSVC,MSWIND 在project-settings-Link-Category-Input-Ignore libraries:栏目中添加:msvcrt.lib 2. 添加头文件:(假设matlab文件为x.m) #include \"matlab.hpp\" #include x.hpp //假如有从.m编译成.cpp的文件x.hpp 和x.cpp; 在x.cpp中添加#include \"StdAfx.h\" 3.在matlab中的编译方法: 用mcc命令转化为c/c++代码,命令行参数如下: 生成c文件: mcc –t –L C x.m 生成c++文件: mcc –t –L Cpp x.m 生成动态链接库函数: mcc –t –W lib:y –T link.lib x.m(y为生成的链接文件名) 4.导入链接库: #pragma comment (lib, \"libmatlb.lib\") #pragma comment (lib, \"libmx.lib\") #pragma comment (lib, \"libmatpm.lib\") // c++ maths library 5.参考代码如下: double d[] = { 1, 2, 3, 4 }; mwArray A(2, 2, d); mwArray arrVal,arrVec; arrVec = eig(&arrVal,A); double* a = new double[4]; double* b = new double[4]; for (int i=0; i < 4; i++) { a[i] = *(mxGetPr(arrVal.GetData())+i); //正序 b[i] = *(mxGetPr(arrVec.GetData())+i);//逆序 } (完) 因篇幅问题不能全部显示,请点此查看更多更全内容