天天看點

matlab混編C++

最近在看的代碼裡有一部分是matlab與c++進行混編的,借這個機會學習了一下matlab的混編方法。

衆所周知,matlab強大的處理矩陣能力在面臨其極慢的執行速度時往往讓人十分抓狂,于是就有了matlab與C/C++等混編情況的出現了。

首先聲明一下,我的matlab版本是2015b(持續更新),vs是2010(懶得換了)。不過vs的版本對于matlab混編沒有影響。

matlab混編常用的指令有三個:mcc、mex、mbuild。

mcc将M檔案轉換成C/C++檔案和相應的MEX包裹檔案(需要Matlab編輯器),但在特定條件下可以自動調用mbuild或者mex。

mex将C/C++檔案(入口函數為mexfunction())編譯成MEX(DLL)檔案(需要C/C++編輯器)。

mbuild将C/C++檔案(入口函數為main())生成可獨立運作的C應用程式(需要C/C++編輯器)。

對于從來沒有進行過混編的matlab,要先進行配置matlab混編的環境。

配置結束後,我們以插值函數為例看看混編的效果。

matlab的混編有很多情況,個人“将m檔案轉換為庫檔案使用”是最簡單也是最常見的一種方式。

mcc -W cpplib:my -T link:lib spline.m
           

-W 指定包裝函數類型,cpplib是生成c++庫檔案;-T指定輸出檔案的目标階段 link:lib是把連結檔案加到共享庫

得到下列檔案:

matlab混編C++

我們使用其中的dlll、h和lib檔案。

第二步是在vs中建立一個控制台應用程式。由于matlab是64位的,是以需要把平台的參數由Win32改為x64(在生成–>配置管理器中)

由于我們需要用到matlab提供的庫檔案和頭檔案,是以需要在項目中将這些目錄添加進來(對這裡不清晰的同學可以Google一下庫檔案和頭檔案相關内容,目錄的添加在項目–>屬性–>vc++目錄中的包含目錄和庫目錄)。我們用到的頭檔案和庫檔案matlab已經提供了,在%\MATLAB\R2015b\extern下,分别是include檔案夾和lib檔案夾。

還要添加附加依賴項。這個可以在屬性的輸入中添加,也可以在程式中添加

#pragma comment(lib,"mclmcrrt.lib")
#pragma comment(lib,"myspline.lib")
           

PS:個人比較支援在項目屬性裡面添加。

工程的主函數比較簡單,隻是調用了混編得到的子函數罷了,函數的實作可以在上圖所示的cpp檔案中檢視。

下面給出主函數的實作代碼:

#include "my.h" // 增加頭檔案
#include <cmath>
#include <iostream>
#include <iomanip>
using namespace std;


// 附加依賴項沒有在屬性頁添加則需加下面兩句
// #pragma comment(lib,"mclmcrrt.lib")
// #pragma comment(lib,"my.lib")



int main()
{
    // 初始化lib(必須)
    if (!myInitialize())
        return -;

    int i, j;
    double x[], y[];
    for(i=; i<; i++)
    {
        x[i] = i;
        y[i] = sin(x[i]);
    }

    double xx[];
    for(i=; i<; i++)
        xx[i] = i*;

    double yy[];

    mwArray mwX(,,mxDOUBLE_CLASS);
    mwArray mwY(,,mxDOUBLE_CLASS);
    mwArray mwXX(,,mxDOUBLE_CLASS);
    mwArray mwYY(,,mxDOUBLE_CLASS);
    mwX.SetData(&(mxDouble)*x, ); // SetData的第一個參數是mxDouble*類型,而x是double
    mwY.SetData(&(mxDouble)*y, );
    mwXX.SetData(&(mxDouble)*xx, );
    mwYY.SetData(&(mxDouble)*yy, );

    spline(, mwYY, mwX, mwY, mwXX); // 調用spline

    cout<<"yy = "<<endl;
    i = ;
    for(j = ; j < ; j++)
    {
        // Get第一個參數表示用1個下标通路元素,j+1是列号(MATLAB下标從1開始,而C++從0開始,故做+1操作)
        yy[j] = mwYY.Get(,j+);
        cout<<setprecision()<<right<<setw()<<yy[j];
        i++;
        if(i% == ) cout<<endl; // 換行
    }
    cout<<endl;

    // 終止調用
    myTerminate();
    getchar();
    return ;
}
           

運作程式即可得到自變量0-10,步長0.25的正弦函數插值結果了。

其他還有将m檔案轉換為對應的C\C++檔案或者利用圖形庫畫圖等,可以參考使用MATLAB的MCC指令生成C/C++程式 和mcc、mbuild和mex指令詳解

如果對本文圖檔中生成的dll、lib、def、exp等檔案心存疑惑,可以參考.dll,.lib,.def 和 .exp檔案

mcc較為詳細的參數參見matlab生成C++檔案mcc指令