使用C++(VS2017)運行Matlab2018a生成的動態鏈接庫DLL

一、Matlab生成動態鏈接庫DLL

前提:電腦中有C/C++編譯器(例如VS)

1、在matlab中打開需要生成的文件 “文件名.m”

例如Main.m

2、在下方命令行中輸入

mex -setup

選擇使用C/C++的compiler;

3、再輸入

mbuild -setup

選擇使用C/C++的builder,注意與上一致;

4、生成動態鏈接庫DLL

輸入

mcc -W lib:動態鏈接庫名稱  -T link:lib 文件名.m

生成C的DLL;

輸入

mcc -W cpplib:動態鏈接庫名稱  -T link:lib 文件名.m

生成C++的DLL;

5、生成下列文件(我的動態鏈接庫名稱爲mydll

【注意】符號計算(例如syms)/神經網絡工具包都不能在打包後被調用

建議改寫爲數值計算。

二、配置VS2017

1、新建一個控制檯project,將上述生成的文件複製到這個工程文件夾下面;

3、Matlab與VS的位數一致(都是x86或者x64)

若Matlab是x64,而VS是x86,則會報錯:

警告	LNK4272	庫計算機類型“x64”與目標計算機類型“x86”衝突

修改VS到x64的方法如下:

(1)右側解決方案中,右擊,“屬性->鏈接器->高級->目標計算機”設置爲"MachineX64 (/MACHINE:X64)";

(2)“屬性->鏈接器->命令行->其他選項”設置爲" /machine:X64 /debug ";

(3)“生成->配置管理器->活動解決方案平臺”勾選兩個對應於“Win32”(x64)的選項;

(4)“生成->配置管理器->活動解決方案平臺”設置爲" X64 "。

3、添加路徑

(1)右側解決方案中,右擊,“屬性->VC++目錄->包含目錄”,編輯添加

...自己補全安裝目錄\MATLABr2018a\extern\lib\win64\microsoft

(2)“屬性->VC++目錄->庫目錄”,編輯添加

...自己補全安裝目錄\MATLABr2018a\extern\include

(3)“屬性->鏈接器->輸入->附加依賴項”

mydll.lib
mclmcrrt.lib

(4)如果提示“mclmcrrt.h”不存在

在安裝目錄\MATLABr2018a\extern\lib\win64\microsoft中找到這個文件,然後複製到在工程下的自己新建lib文件夾,“屬性->VC++目錄->引用目錄”,編輯添加這個lib文件夾。

(5)在“我的電腦->系統變量->path”

添加 matlab到win64的路徑,例如:

E:\MATLABr2018a\bin\win64

三、運行DLL

VS主函數main的簡單框架如下:

#include "stdafx.h"
#include "mydll.h"

int main()
{

	mydllInitialize();            //初始化DLL動態連接文件
	mxArray *input[1];            //將輸入參數傳遞進去,根據自己需要補充代碼設置
	mxArray *output[1];           //定義輸出參數指針
	mlxMain(1, output, 1, input); //調用m函數,即mlx+.m中的函數名
	mydllTerminate();             //結束DLL庫
}

函數的對應改寫方法可以參考https://ww2.mathworks.cn/help/compiler_sdk/cxx/matlab-compiler-generated-interface-functions.html

如果編譯成功但是F5運行時拋出異常:

********處(位於dlltest.exe 中)引發的異常: 0xC0000005: 讀取位置 0x00000000 時發生訪問衝突

Ctrl+Alt+E取消Win32 Exceptions

或者在vs2017界面-->調試-->異常設置-->取消勾選Win32 Exceptions

四、參數變量定義與函數調用

參數有兩種格式,對應於調用的函數的兩種格式,具體可以看mydll.h代碼文件

(1)

bool MW_CALL_CONV mlx函數名(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);

VS中調用的函數是“mlx函數名”,參數列表分別是:輸入參數個數,輸入參數,輸出參數個數,輸出參數。

mxArray* 參數1 = mxCreateString("your string");//string

(2)

extern LIB_mydll_CPP_API void MW_CALL_CONV 函數名(const mwArray& 參數1, const mwArray& 參數2);

VS中調用的函數是“函數名”,參數列表分別是:輸入參數1,輸出參數2。

mwArray 參數1 = "your string";//string
mwArray 參數2(true);//bool

五、抄送一個Demo

matlab:

function b = MyFunc(a)
b = a.*a;

生成:

mcc –W cpplib:mydll –T link:lib MyFunc.m –C

VS2017:

// dlltest.cpp: 定義控制檯應用程序的入口點。
//

#include "stdafx.h"
#include "mydll.h"
using namespace std;
int main()
{
	cout << "start" << endl;
	if (mydllInitialize())    //必須的要初始化,格式爲  名字Initialize()
	{
		cout << "success" << endl;
	}
	else
	{
		cout << "fail" << endl;
		return 0;
	}
	//mydllInitialize();                            //初始化DLL動態連接文件
	system("pause");
	double _x[5] = { 1,2,3,4,5 };                //輸入數組
	double _y[5];                             //輸出數組
	mxArray* x = mxCreateDoubleMatrix(1, 5, mxREAL);     //創建1*5矩陣
	memcpy(mxGetPr(x), (void*)_x, sizeof(_x));           //拷貝輸入數據
	mxArray *input[1] = { x };                               //將矩陣x的指針作爲輸入參數傳遞進去
	mxArray *output[1];                                    //定義輸出參數指針
	mlxMyFunc(1, output, 1, input);                       //調用m函數
	mxArray *y;                                        //定義輸出結果指針
	y = output[0];                                     //將輸出參數傳遞給輸出結果
	memcpy(_y, mxGetPr(y), sizeof(_y));                //拷貝輸出數據
	mydllTerminate();                    //結束DLL庫
	 //顯示數組中的數據
	string str;
	cout << _y[0] << endl; 
	cout << _y[1] << endl;
	cout << _y[2] << endl;
	cout << _y[3] << endl;
	cout << _y[4] << endl;
	system("pause");
}

運行結果:

六、參考來源

https://blog.csdn.net/wcq1973/article/details/51177614

https://blog.csdn.net/sheng_bw/article/details/86004709

https://blog.csdn.net/qq_20515461/article/details/81229726

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章