本章教程共分為7篇進(jìn)行闡述:
MATLAB編程與應(yīng)用系列-第16章 外部接口技術(shù)(1)
MATLAB編程與應(yīng)用系列-第16章 外部接口技術(shù)(2)
MATLAB編程與應(yīng)用系列-第16章 外部接口技術(shù)(3)
MATLAB編程與應(yīng)用系列-第16章 外部接口技術(shù)(4)
MATLAB編程與應(yīng)用系列-第16章 外部接口技術(shù)(5)
MATLAB編程與應(yīng)用系列-第16章 外部接口技術(shù)(6)
MATLAB編程與應(yīng)用系列-第16章 外部接口技術(shù)(7)
本系列教程來源于出版書籍《基于MATLAB編程基礎(chǔ)與典型應(yīng)用書籍》,如涉及版權(quán)問題,請(qǐng)聯(lián)系:156204968@qq.com。 出版社:人民郵電出版社, 頁(yè)數(shù):525。
本系列教程目前基于MATLABR2006a,可能對(duì)于更高級(jí)版本的功能和函數(shù)有差異,教程中如有問題,請(qǐng)聯(lián)系:156204968@qq.com
16.5 Visual C++與MATLAB接口
MATLAB開發(fā)環(huán)境提供了豐富的應(yīng)用程序接口(API)庫(kù)函數(shù)實(shí)現(xiàn)C,C++與MATLAB的混合編程,通過mex, mbuild, mcc編譯命令可以實(shí)現(xiàn)把M文件編譯成Visual C++環(huán)境下直接調(diào)用的C/C++文件,或者把C文件編譯成在MATLAB開發(fā)環(huán)境中直接調(diào)用的可執(zhí)行文件。在Visual C++中實(shí)現(xiàn)和MATLAB開發(fā)環(huán)境的接口主要有以下幾種方法:
在Visual C++中使用MATLAB引擎,調(diào)用應(yīng)用程序接口(API)中的Engine函數(shù)庫(kù),調(diào)用MATLAB函數(shù),但是該方法在編譯成功后,會(huì)自動(dòng)啟動(dòng)MATLAB開發(fā)環(huán)境,在16.4節(jié)MATLAB引擎技術(shù)一節(jié)中有詳細(xì)介紹;
在Visual C++中直接調(diào)用MATLAB語(yǔ)言C, C++數(shù)學(xué)函數(shù)庫(kù)(Math Library),通過mex和mbuild命令配置MATLAB語(yǔ)言C/C++開發(fā)環(huán)境,實(shí)現(xiàn)Visual C++和MATLAB的接口,編譯形成獨(dú)立與MATLAB環(huán)境的可執(zhí)行.exe文件;
使用C/C++語(yǔ)言編寫MEX文件,在MATLAB中通過MEX命令編譯成MATLAB可以直接運(yùn)行的文件,以實(shí)現(xiàn)Visual C++與MATLAB的接口,在16.2節(jié)MEX文件介紹中,已經(jīng)作了詳細(xì)的探討。
使用MathTools公司開發(fā)的MATCOM可視化界面,將MATLAB文件編譯成Visual C++可以直接執(zhí)行的C++文件,生成的C++文件可以同時(shí)兼顧MATLAB開發(fā)環(huán)境強(qiáng)大的數(shù)學(xué)運(yùn)算功能和C++語(yǔ)言運(yùn)行速度快兩方面的優(yōu)點(diǎn)。使用Visual MATCOM Add-in插件,在Visual C++環(huán)境中直接編譯運(yùn)行M文件。
使用COM((Component Object Model)組件可以實(shí)現(xiàn)MATLAB與Visual C++的接口。 通過MATLAB COM Builder可以把MATLAB開發(fā)的M文件,MEX文件等做成組件,使之成為獨(dú)立的COM對(duì)象,可以被其他支持COM語(yǔ)言的開發(fā)環(huán)境所使用,如Visual C++,Visual Basic,JAVA,Microsoft EXCEL等。
本節(jié)主要介紹通過配置Visual C++編譯環(huán)境,編譯運(yùn)行MEX文件,MAT文件,調(diào)用MATLAB C++數(shù)學(xué)函數(shù)庫(kù),在Visual C++中使用MATLAB引擎,基于MATCOM實(shí)現(xiàn)Visual C++通MATLAB的接口,利用MATLAB COM Builder可視化界面實(shí)現(xiàn)Visual C++和MATLAB的接口。主要內(nèi)容包括:
Visual C++中使用MATLAB引擎
Visual C++中使用MATLAB語(yǔ)言數(shù)學(xué)函數(shù)庫(kù)
Visual C++中創(chuàng)建MAT文件
基于MATCOM實(shí)現(xiàn)Visual C++與MATLAB接口
使用COM組件實(shí)現(xiàn)Visual C++和MATLAB接口
16.5.1 Visual C++中使用MATLAB引擎
在16.4節(jié)MATLAB引擎技術(shù)一節(jié)中,詳細(xì)介紹了在Visual C++環(huán)境下調(diào)用MATLAB引擎的環(huán)境配置和實(shí)例演示,利用MATLAB應(yīng)用程序接口(API)函數(shù)庫(kù)的Engine函數(shù)庫(kù)可以直接調(diào)用MATLAB開發(fā)環(huán)境函數(shù),一方面可以保持C++代碼的運(yùn)行效率,同時(shí)可以使用MATLAB豐富的數(shù)學(xué)函數(shù)庫(kù)函數(shù),各種工程領(lǐng)域工具箱函數(shù)等。但是使用MATLAB引擎技術(shù),生成的應(yīng)用程序無法獨(dú)立與MATLAB平臺(tái)運(yùn)行,通過這種方式進(jìn)行MATLAB函數(shù)調(diào)用,必須要求系統(tǒng)安裝MATLAB安裝程序,這給應(yīng)用程序的移植和推廣帶來難度。以下介紹的一些Visual C++與MATLAB接口技術(shù),可以實(shí)現(xiàn)將MATLAB函數(shù)編譯成.exe文件,動(dòng)態(tài)鏈接庫(kù)文件DLL文件或者編譯成COM組件,可以獨(dú)立與MATLAB開發(fā)平臺(tái)運(yùn)行。
16.5.2 Visual C++中使用MATLAB語(yǔ)言C,C++數(shù)學(xué)函數(shù)庫(kù)
MATLAB開發(fā)環(huán)境的C,C++數(shù)學(xué)函數(shù)庫(kù)以mwArray結(jié)構(gòu)體為數(shù)據(jù)核心,使用mcc命令將M文件轉(zhuǎn)換成的C/C++文件可以直接在Viusal C++開發(fā)環(huán)境中使用,但是編譯后的C,C++文件一般程序冗長(zhǎng),代碼可讀性較差。在熟練掌握C, C++數(shù)學(xué)函數(shù)庫(kù)的基礎(chǔ)上,讀者可以使用mwArray結(jié)構(gòu)體自行編寫基于應(yīng)用程序接口(API)函數(shù)庫(kù)C, C++數(shù)學(xué)庫(kù)的C/C++文件,可以極大優(yōu)化程序代碼,減少程序代碼存儲(chǔ)空間,提高程序代碼的執(zhí)行效率和執(zhí)行速度。在下文的講述中,將通過一個(gè)簡(jiǎn)單實(shí)例來演示如何利用mcc命令創(chuàng)建獨(dú)立與MATLAB平臺(tái)運(yùn)行的exe文件。
首先使用MATLAB的M語(yǔ)言建立用戶所需要的特定功能M 文件,在這里,為了簡(jiǎn)單而言,建立一個(gè)實(shí)現(xiàn)魔方陣功能的M文件magicCreat.m。
function y = magicCreat(n)
y = magic(n)
然后從%matlabroot%\ extern\examples\compiler (%matlabroot%為讀者計(jì)算機(jī)系統(tǒng)中MATLAB的安裝路徑,本文中為C:\Program Files\MATLAB\R2006a\extern\examples\compiler)路徑下拷貝main_for_lib.c和main_for_lib.h.到當(dāng)前的工作路徑下,以便mcc編譯命令調(diào)用。然后創(chuàng)建調(diào)用magicCreat.m文件的C語(yǔ)言程序如下:
#include <stdio.h>
#include <math.h>
#include "libPkg.h" //編譯建立的庫(kù)頭文件
main( int argc, char **argv )
{
mxArray *N; /* 輸入變量矩陣指針 */
mxArray *R = NULL; /* 結(jié)果矩陣指針 */
int n; //默認(rèn)的M文件輸入變量數(shù)值
/* 獲取命令行參數(shù),如果命令行輸入小于2,則輸入?yún)?shù)默認(rèn)為5 */
if (argc >= 2) {
n = atoi(argv[1]);
} else {
n = 5;
}
//初始化MCR和libPkg函數(shù)庫(kù)
mclInitializeApplication(NULL,0);
libPkgInitialize();
/* 得到輸入?yún)⒘康臄?shù)值 */
N = mxCreateDoubleScalar(n);
/*調(diào)用magicCreat.m編譯后的文件mlfMagicCreat*/
mlfMagicCreat(1, &R, N);
/* 釋放內(nèi)存空間*/
mxDestroyArray(N);
mxDestroyArray(R);
//結(jié)束libPkg庫(kù)和MCR
libPkgTerminate();
mclTerminateApplication();
}
其中l(wèi)ibPkg.h為mcc命令編譯后的庫(kù)文件,該文件結(jié)構(gòu)清晰,首先程序代碼包含相關(guān)必要的頭文件和libPkg.h文件,主程序入口,變量的定義,然后初始化MCR和libPkg函數(shù)庫(kù),調(diào)用magicCreat.m編譯后的文件mlfMagicCreat,調(diào)用結(jié)果用矩陣R存儲(chǔ),最后釋放內(nèi)存空間,并結(jié)束libPkg庫(kù)和MCR。在程序結(jié)束之前及時(shí)地釋放內(nèi)存空間是一個(gè)很好的編程習(xí)慣。將該程序存儲(chǔ)為magicCreatCFile.c,接下來使用mcc命令編譯該文件,在MATLAB命令行窗口中輸入:
mcc -W lib:libPkg -T link:exe magicCreat magicCreatCFile.c main_for_lib.c
經(jīng)過mcc命令編譯后,可以發(fā)現(xiàn)在當(dāng)前路徑下,出現(xiàn)一個(gè)magicCreat.exe文件,為一個(gè)可執(zhí)行程序文件,在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
程序正常運(yùn)行,由于命令行輸入變量個(gè)數(shù)小于2,因此M文件輸入?yún)?shù)默認(rèn)值為5,程序產(chǎn)生一個(gè)5階的魔方陣,如果需要輸入第2個(gè)輸入?yún)?shù),則可以按照以下方式在MATLAB命令行窗口中輸入:
>> !magicCreat 3 %創(chuàng)建一個(gè)3階的魔方陣
y =
8 1 6
3 5 7
4 9 2
16.5.3 Visual C++中創(chuàng)建MAT文件
在16.3節(jié)MAT數(shù)據(jù)文件一節(jié)中,介紹了MAT數(shù)據(jù)文件的基本概念,如何編寫MEX文件寫入和讀出MAT數(shù)據(jù)文件。在Visual C++開發(fā)環(huán)境中,同樣可以利用API函數(shù)庫(kù)的MAT函數(shù)庫(kù),寫入和讀出MAT數(shù)據(jù)文件。通過這種數(shù)據(jù)文件的讀寫,可以有效地實(shí)現(xiàn)Visual C++環(huán)境同MATLAB開發(fā)環(huán)境的數(shù)據(jù)通信接口。
以下matCreatCDemo.c文件為在Visual C++環(huán)境下實(shí)現(xiàn)MAT數(shù)據(jù)文件的讀寫操作,程序代碼如下:
/*
* 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;
// 初始數(shù)據(jù)定義
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};
// 創(chuàng)建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);
}
// 創(chuàng)建字符串mxArray數(shù)據(jù)結(jié)構(gòu)變量
pString = mxCreateString("This is the MAT demo in C lanuage! Enojy it~!");
if (pString == NULL)
{
printf("ERROR: Unable to create string!");
return(EXIT_FAILURE);
}
//創(chuàng)建矩陣mxArray數(shù)據(jù)結(jié)構(gòu)變量
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);
}
// 將初始數(shù)據(jù)拷貝給mxArray數(shù)據(jù)結(jié)構(gòu)變量
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);
}
// 釋放內(nèi)存空間
mxDestroyArray(pString);
mxDestroyArray(pArray1);
mxDestroyArray(pArray2);
// 關(guān)閉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文件的數(shù)據(jù)變量
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);
}
// 釋放內(nèi)存空間
mxDestroyArray(pArray1);
mxDestroyArray(pArray2);
mxDestroyArray(pString);
// 關(guān)閉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++環(huán)境新建一個(gè)Win32 Consol Application工程,命名為MatCreatCDemo,Visual C++環(huán)境的設(shè)置參考16.4.1節(jié)的設(shè)置。輸入以上程序段后,編譯運(yùn)行,程序結(jié)果如圖16.7所示:

在MatCreatCDemo工程目錄下,可以看到新建立的MatDemo.mat文件,將工程目錄下的MatDemo.mat文件拷貝到MATLAB的工作路徑下,使用load命令可以查看MatDemo文件中的數(shù)據(jù),在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
作者:德特?cái)?shù)據(jù)
聯(lián)系方式:156204968@qq.com