先小話一下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的動態鏈結了。
利用C 和Matlab混合程式設計
在c 中引用 dll 檔案 如何引用 程式設計中c 資料型別的轉換 兩者之間的函式變數的傳遞時如何實現的 需要額外新增的dllmwarray.dll 在安裝目錄的toolbox dotnetbuilder bin win64 v2.0資料夾中 脫離matlab安裝的環境下,如何使得程式執行自如 c ...
c 與matlab混合程式設計
實驗平台 matlab r2016b vs2013 思路 1.設定matlab的編譯器,使用外部的vc或者gcc等編譯器。2.編譯m檔案成dll 3.設定vs的include路徑和lib鏈結庫的路徑 4.編寫c 呼叫dll 步驟 1.設定matlab的編譯器 在命令列視窗下,輸入並執行如下命令 me...
C 與matlab混合程式設計
環境 vs2010 matlab2010 首先,編寫乙個函式集的.m檔案。函式名稱 class netbuilder func 1 function y class netbuilder func f 2 t linspace 0,1,400 3 y sin 2 pi f t 4plot t,y 5...