【Matlab】C++和MATLAB混合編程-DLL篇

來源:互聯網
上載者:User

先小話一下DLL,DLL是動態連結程式庫,是原始碼編譯後的二進位庫檔案和程式介面,和靜態連結庫不同的是,程式在編譯時間並不連結動態連結程式庫的執行體,而是在檔案中保留一個調用標記,在程式運行時才將動態連結程式庫檔案載入入記憶體。並且DLL在運行時是共用的,即當多個程式調用時,記憶體中也只保持一份動態連結程式庫。

動態連結程式庫的調用有顯式和隱式兩種方式。

隱式連結需要用到我們前面產生的plotdata.c,plotdata.h,plotdata.lib以及plotdata.dll檔案。
首先將plotdata.c,plotdata.h加入工程中,注意在需要用到函數的檔案加入#include “plotdata.h”。
之後連結輸入項中寫上plotdata.lib。右擊工程->Propertites->Link->Input->Additional Dependecies中加上plotdata.lib(也就是在調用MATLAB引擎時填寫libmat.lib、libeng.lib等的地方)注意plotdata.lib也需要放在你的工程下,或者寫全路徑,如"D:\data\plotadata.lib",需要加引號。
這樣在你的代碼中就可以直接用plotdata.h中的介面函數了。

另顯式連結的方式:所謂“顯式”說白了就是在代碼中寫出來我要調用這個DLL。

首先我們需要定義一個函數類型,方便我們後面進行函數的強制類型轉換。我們可以在plotdata.h中找到我們將要使用的函數plotdata,他的函式宣告如下:

extern LIB_plotdata_CPP_API void MW_CALL_CONV plotdata(const mwArray& rgbData);

忽略那些複雜的宏定義,模仿著定義我們自己的函數類型:

typedef void (*HMAT)(const mwArray& rgbData);

之後在代碼中顯式連結plotdata.dll

HINSTANCE hDLL=NULL;//DLL控制代碼hDLL=LoadLibrary("plotdata.dll");HMAT plotData=(HMAT)GetProcAddress(hDLL,"plotdata");                //第一個參數為DLL控制代碼,第二個為要載入的函數名

之後便可直接在代碼中直接使用函數plotData了。這種顯式連結只需要plotdata.dll檔案即可~
下面我們來看一下產生的函數介面

extern LIB_plotdata_C_API bool MW_CALL_CONV plotdataInitializeWithHandlers(       mclOutputHandlerFcn error_handler,        mclOutputHandlerFcn print_handler);extern LIB_plotdata_C_API bool MW_CALL_CONV plotdataInitialize(void);extern LIB_plotdata_C_API void MW_CALL_CONV plotdataTerminate(void);extern LIB_plotdata_C_API void MW_CALL_CONV plotdataPrintStackTrace(void);extern LIB_plotdata_C_API bool MW_CALL_CONV mlxPlotdata(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);extern LIB_plotdata_C_API long MW_CALL_CONV plotdataGetMcrID();extern LIB_plotdata_C_API bool MW_CALL_CONV mlfPlotdata(mxArray* rgbData);

這是plotdata.h中主要的函數。plotdataInitialize(void)可以看出是初始化的函數。如果是隱式連結DLL最好先調用此函數,判斷傳回值否則很可能載入不到dll,而在顯式連結時,如果沒有載入函數成功,也不會直接報錯,但我們可以在單步調試時看函數是否為分配了記憶體(即是否為null)。plotdataTerminate(void)是終止動態連結程式庫的函數。
mlxPlotdatat與mlfPlotdata是最關鍵的兩個介面,也是我們要載入的函數。他們執行的功能與m檔案中plotdata函數是一樣的。兩個函數輸入參數不同:
mlxPlotdata(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]); 其中 nlhs,plhs分別表示輸出參數的個數及輸出參數的mxArray數組;nrhs,prhs表示輸入參數的個數及輸入參數數組。(這個函數有點通用的感覺……)
mlfPlotdata(mxArray* rgbData); 就簡單的多,基本和m檔案中你定義的plotdata函數是一樣的(我的plotdata定義為 function []=plotdata(rgbData))
所以一般在程式中載入的是mlf開頭的函數。
這裡需要提的是我編譯產生的是C的動態連結程式庫。如果是產生C++的動態連結程式庫,產生的介面函數也帶有一個mlx開頭的函數,即
bool MW_CALL_CONV mlxPlotdata(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
但是另一個函數是不帶有mlf的,直接為
void MW_CALL_CONV plotdata(const mwArray& rgbData)
而且輸入參數不是mxArray數組,而是mwArray數組,這也是C和C++與MATLAB混合編程時最主要的不同(下篇再詳細說)
但是我在嘗試C++動態連結時一直沒有成功。後來看到產生的cpp檔案同c檔案一樣也有一個 extend "C"{},這是C++為了與C相容而提供的一個關鍵字,C++編譯器將會在extend "C"的大括弧內部代碼當做C語言代碼處理,這讓我很困惑……而如果注釋掉又會報串連錯誤
想來可能是MATLAB對C++編譯支援並不好(他內建的lcc編譯器是只能編譯成C的介面)總之沒有嘗試成功,暫時在程式中都用C的動態連結了。

(轉載請註明作者和出處:http://blog.csdn.net/xiaowei_cqu 未經允許請勿用於商業用途)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.