本章教程共分为7篇进行阐述:
MATLAB编程与应用系列-第16章 外部接口技术(1)
MATLAB编程与应用系列-第16章 外部接口技术(2)
MATLAB编程与应用系列-第16章 外部接口技术(3)
MATLAB编程与应用系列-第16章 外部接口技术(4)
MATLAB编程与应用系列-第16章 外部接口技术(5)
MATLAB编程与应用系列-第16章 外部接口技术(6)
MATLAB编程与应用系列-第16章 外部接口技术(7)
本系列教程来源于出版书籍《基于MATLAB编程基础与典型应用书籍》,如涉及版权问题,请联系:156204968@qq.com。 出版社:人民邮电出版社, 页数:525。
本系列教程目前基于MATLABR2006a,可能对于更高级版本的功能和函数有差异,教程中如有问题,请联系:156204968@qq.com
16.5 Visual C++与MATLAB接口
MATLAB开发环境提供了丰富的应用程序接口(API)库函数实现C,C++与MATLAB的混合编程,通过mex, mbuild, mcc编译命令可以实现把M文件编译成Visual C++环境下直接调用的C/C++文件,或者把C文件编译成在MATLAB开发环境中直接调用的可执行文件。在Visual C++中实现和MATLAB开发环境的接口主要有以下几种方法:
在Visual C++中使用MATLAB引擎,调用应用程序接口(API)中的Engine函数库,调用MATLAB函数,但是该方法在编译成功后,会自动启动MATLAB开发环境,在16.4节MATLAB引擎技术一节中有详细介绍;
在Visual C++中直接调用MATLAB语言C, C++数学函数库(Math Library),通过mex和mbuild命令配置MATLAB语言C/C++开发环境,实现Visual C++和MATLAB的接口,编译形成独立与MATLAB环境的可执行.exe文件;
使用C/C++语言编写MEX文件,在MATLAB中通过MEX命令编译成MATLAB可以直接运行的文件,以实现Visual C++与MATLAB的接口,在16.2节MEX文件介绍中,已经作了详细的探讨。
使用MathTools公司开发的MATCOM可视化界面,将MATLAB文件编译成Visual C++可以直接执行的C++文件,生成的C++文件可以同时兼顾MATLAB开发环境强大的数学运算功能和C++语言运行速度快两方面的优点。使用Visual MATCOM Add-in插件,在Visual C++环境中直接编译运行M文件。
使用COM((Component Object Model)组件可以实现MATLAB与Visual C++的接口。 通过MATLAB COM Builder可以把MATLAB开发的M文件,MEX文件等做成组件,使之成为独立的COM对象,可以被其他支持COM语言的开发环境所使用,如Visual C++,Visual Basic,JAVA,Microsoft EXCEL等。
本节主要介绍通过配置Visual C++编译环境,编译运行MEX文件,MAT文件,调用MATLAB C++数学函数库,在Visual C++中使用MATLAB引擎,基于MATCOM实现Visual C++通MATLAB的接口,利用MATLAB COM Builder可视化界面实现Visual C++和MATLAB的接口。主要内容包括:
Visual C++中使用MATLAB引擎
Visual C++中使用MATLAB语言数学函数库
Visual C++中创建MAT文件
基于MATCOM实现Visual C++与MATLAB接口
使用COM组件实现Visual C++和MATLAB接口
16.5.1 Visual C++中使用MATLAB引擎
在16.4节MATLAB引擎技术一节中,详细介绍了在Visual C++环境下调用MATLAB引擎的环境配置和实例演示,利用MATLAB应用程序接口(API)函数库的Engine函数库可以直接调用MATLAB开发环境函数,一方面可以保持C++代码的运行效率,同时可以使用MATLAB丰富的数学函数库函数,各种工程领域工具箱函数等。但是使用MATLAB引擎技术,生成的应用程序无法独立与MATLAB平台运行,通过这种方式进行MATLAB函数调用,必须要求系统安装MATLAB安装程序,这给应用程序的移植和推广带来难度。以下介绍的一些Visual C++与MATLAB接口技术,可以实现将MATLAB函数编译成.exe文件,动态链接库文件DLL文件或者编译成COM组件,可以独立与MATLAB开发平台运行。
16.5.2 Visual C++中使用MATLAB语言C,C++数学函数库
MATLAB开发环境的C,C++数学函数库以mwArray结构体为数据核心,使用mcc命令将M文件转换成的C/C++文件可以直接在Viusal C++开发环境中使用,但是编译后的C,C++文件一般程序冗长,代码可读性较差。在熟练掌握C, C++数学函数库的基础上,读者可以使用mwArray结构体自行编写基于应用程序接口(API)函数库C, C++数学库的C/C++文件,可以极大优化程序代码,减少程序代码存储空间,提高程序代码的执行效率和执行速度。在下文的讲述中,将通过一个简单实例来演示如何利用mcc命令创建独立与MATLAB平台运行的exe文件。
首先使用MATLAB的M语言建立用户所需要的特定功能M 文件,在这里,为了简单而言,建立一个实现魔方阵功能的M文件magicCreat.m。
function y = magicCreat(n)
y = magic(n)
然后从%matlabroot%\ extern\examples\compiler (%matlabroot%为读者计算机系统中MATLAB的安装路径,本文中为C:\Program Files\MATLAB\R2006a\extern\examples\compiler)
路径下拷贝main_for_lib.c
和main_for_lib.h
.到当前的工作路径下,以便mcc编译命令调用。然后创建调用magicCreat.m文件的C语言程序如下:
#include <stdio.h>
#include <math.h>
#include "libPkg.h" //编译建立的库头文件
main( int argc, char **argv )
{
mxArray *N; /* 输入变量矩阵指针 */
mxArray *R = NULL; /* 结果矩阵指针 */
int n; //默认的M文件输入变量数值
/* 获取命令行参数,如果命令行输入小于2,则输入参数默认为5 */
if (argc >= 2) {
n = atoi(argv[1]);
} else {
n = 5;
}
//初始化MCR和libPkg函数库
mclInitializeApplication(NULL,0);
libPkgInitialize();
/* 得到输入参量的数值 */
N = mxCreateDoubleScalar(n);
/*调用magicCreat.m编译后的文件mlfMagicCreat*/
mlfMagicCreat(1, &R, N);
/* 释放内存空间*/
mxDestroyArray(N);
mxDestroyArray(R);
//结束libPkg库和MCR
libPkgTerminate();
mclTerminateApplication();
}
其中libPkg.h为mcc命令编译后的库文件,该文件结构清晰,首先程序代码包含相关必要的头文件和libPkg.h文件,主程序入口,变量的定义,然后初始化MCR和libPkg函数库,调用magicCreat.m编译后的文件mlfMagicCreat,调用结果用矩阵R存储,最后释放内存空间,并结束libPkg库和MCR。在程序结束之前及时地释放内存空间是一个很好的编程习惯。将该程序存储为magicCreatCFile.c
,接下来使用mcc命令编译该文件,在MATLAB命令行窗口中输入:
mcc -W lib:libPkg -T link:exe magicCreat magicCreatCFile.c main_for_lib.c
经过mcc命令编译后,可以发现在当前路径下,出现一个magicCreat.exe文件,为一个可执行程序文件,在MATLAB命令行窗口输入:
>> !magicCreat
Extracting CTF archive. This may take a few seconds, depending on the
size of your application. Please wait...
...CTF archive extraction complete.
y =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
程序正常运行,由于命令行输入变量个数小于2,因此M文件输入参数默认值为5,程序产生一个5阶的魔方阵,如果需要输入第2个输入参数,则可以按照以下方式在MATLAB命令行窗口中输入:
>> !magicCreat 3 %创建一个3阶的魔方阵
y =
8 1 6
3 5 7
4 9 2
16.5.3 Visual C++中创建MAT文件
在16.3节MAT数据文件一节中,介绍了MAT数据文件的基本概念,如何编写MEX文件写入和读出MAT数据文件。在Visual C++开发环境中,同样可以利用API函数库的MAT函数库,写入和读出MAT数据文件。通过这种数据文件的读写,可以有效地实现Visual C++环境同MATLAB开发环境的数据通信接口。
以下matCreatCDemo.c文件为在Visual C++环境下实现MAT数据文件的读写操作,程序代码如下:
/*
* matCreatCDemo.c
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mat.h"
int main()
{
//MATFile文件定义,mxArray变量定义
const char *filename = "MatDemo.mat";
MATFile *file;
int flag1,flag2,flag3;
mxArray *pString, *pArray1, *pArray2;
// 初始数据定义
double a1[] = {0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0};
double a2[] = {9.0, 4.0,5.4,6.4,3.2,1.5};
// 创建MAT文件
printf("Creating file %s...\n\n",filename);
file = matOpen(filename,"w");
if ( file == NULL )
{
printf("ERROR: Can not create file %s\n", filename);
return(EXIT_FAILURE);
}
// 创建字符串mxArray数据结构变量
pString = mxCreateString("This is the MAT demo in C lanuage! Enojy it~!");
if (pString == NULL)
{
printf("ERROR: Unable to create string!");
return(EXIT_FAILURE);
}
//创建矩阵mxArray数据结构变量
pArray1 = mxCreateDoubleMatrix(3,3,mxREAL);
pArray2 = mxCreateDoubleMatrix(2,3,mxREAL);
if( (pArray1 == NULL)||(pArray2 ==NULL) )
{
printf("Error: Cannot create the double matrix!");
return(EXIT_FAILURE);
}
// 将初始数据拷贝给mxArray数据结构变量
memcpy( (void *)(mxGetPr(pArray1)), (void *)a1, sizeof(a1));
memcpy( (void *)(mxGetPr(pArray2)), (void *)a2, sizeof(a2));
// 向MAT文件中写入变量
flag1 = matPutVariable(file, "variableString", pString);
flag2 = matPutVariable(file, "variableDoubleMatrix1", pArray1);
flag3 = matPutVariable(file, "variableDoubleMatrix2", pArray2);
if(( flag1 != 0)||(flag2 != 0)||(flag3 != 0))
{
printf("Can not write variable into the file %s \n", filename);
return(EXIT_FAILURE);
}
// 释放内存空间
mxDestroyArray(pString);
mxDestroyArray(pArray1);
mxDestroyArray(pArray2);
// 关闭MAT文件
if(matClose(file) != 0)
{
printf("ERROR: Can not close %s file.\n",filename);
return(EXIT_FAILURE);
}
// 重新打开MAT文件
file = matOpen(filename, "r");
if (file == NULL)
{
printf("ERROR: Can not open file %s\n", filename);
return(EXIT_FAILURE);
}
// 读取MAT文件的数据变量
pArray1 = matGetVariable(file, "variableDoubleMatrix1");
pArray2 = matGetVariable(file, "variableDoubleMatrix2");
pString = matGetVariable(file, "variableString");
if ( (pArray1 == NULL) || (pArray2 == NULL) ||(pString == NULL))
{
printf("ERROR: Can not reading variables from file %s\n",filename);
return(EXIT_FAILURE);
}
// 释放内存空间
mxDestroyArray(pArray1);
mxDestroyArray(pArray2);
mxDestroyArray(pString);
// 关闭MAT文件
if (matClose(file) != 0)
{
printf("ERROR: Can not close file %s\n",filename);
return(EXIT_FAILURE);
}
printf("Complete!\n");
return(EXIT_SUCCESS);
}
在Visual C++环境新建一个Win32 Consol Application工程,命名为MatCreatCDemo,Visual C++环境的设置参考16.4.1节的设置。输入以上程序段后,编译运行,程序结果如图16.7所示:
在MatCreatCDemo工程目录下,可以看到新建立的MatDemo.mat文件,将工程目录下的MatDemo.mat文件拷贝到MATLAB的工作路径下,使用load命令可以查看MatDemo文件中的数据,在MATLAB命令行窗口中输入:
>> load MatDemo
>> whos
Name Size Bytes Class
variableDoubleMatrix1 3x3 72 double array
variableDoubleMatrix2 2x3 48 double array (global)
variableString 1x43 86 char array
Grand total is 58 elements using 206 bytes
作者:德特数据
联系方式:156204968@qq.com