欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

QT與MATLAB混合編程的詳細教程

 更新時間:2023年01月18日 11:37:48   作者:一天不學我渾身難受  
最近項目需要,matlab的一些算法需要工程用,因此需要直接轉成Qt能夠調用的形式,下面這篇文章主要給大家介紹了關于QT與MATLAB混合編程的相關資料,需要的朋友可以參考下

QT與MATLAB混合編程

本文就介紹使用 Qt 和 Matlab 進行混合編程的基本流程,主要包括:

  • 如何在Matlab中將m文件編譯為C++語言的DLL文件
  • 如何在Qt項目中加入自定義DLL相關的LIB文件,以及MATLAB相關的LIB文件和H文件搜索路徑
  • MATLAB運行時DLL文件所在路徑,及系統(tǒng)相關的環(huán)境變量設置
  • 如何在Qt中調用自定義DLL中的函數(shù),如何通過mwArray類傳遞輸入輸出參數(shù)

一、環(huán)境

  • Win10
  • Qt 5.14.2 (MSVC 2017, 32 bit)
  • matlab R2016b
  • vs2017

二、將matlab程序寫成函數(shù)形式

在MATLAB中編寫一個畫有向圖的函數(shù)Matlab_Digraph.m為例,其代碼如下:

function Matlab_Digraph(fullLineS,fullLineT,v,dottedLineS,dottedLineT,taskNum,jobId,oper,iCriticalPathS,iCriticalPathT,select)
close all;
figure('NumberTitle', 'off','Name', '有向圖');
nodenames=cell(1,taskNum+2);
for i=1:taskNum+2
    if i==1
    nodenames{1,i}='開始';
    elseif i==taskNum+2
    nodenames{1,i}='結束';
    else
    txt = sprintf('J%d.%d(%d)',jobId(i-1),oper(i-1),v(i-1));
    nodenames{1,i}=txt;   
    end
end
G= digraph(fullLineS,fullLineT,[],nodenames);
p=plot(G,'Layout','force');
p.ArrowSize=15;                                        %箭頭大小
p.LineWidth=2;                                         %線寬
p.EdgeColor ='black';                                  %線顏色
p.Marker = 'o';                                        %節(jié)點標記符號
p.MarkerSize=10;                                       %節(jié)點大小
p.NodeColor = 'cyan';                                  %節(jié)點顏色
set( gca,'XTick' ,[] ,'YTick',[]);
highlight(p,dottedLineS,dottedLineT,'LineStyle','--') ;
if select==1
    highlight(p,iCriticalPathS,iCriticalPathT,'EdgeColor','r','LineWidth',5) ;
end
end

在matlab中運行一下,如:

% 函數(shù)digraph(s,t,v):可在 s 和 t 中的對應節(jié)點之間創(chuàng)建邊,并生成一個圖
% s 和 t 都必須具有相同的元素數(shù);這些節(jié)點必須都是從1開始的正整數(shù),或都是字符串元胞數(shù)組。
>> fullLineS=[1  1  5  1  3  8  7  2  6  9  4  10  2  3  5  6  8  9];
>> fullLineT= [2  3  4  5  6  7  11  8  9  11  10  11  3  4  6  7  9  10 ];
>> v=[3 2 4 3 3 3 3 5 3];
>> dottedLineS=[1 2 3];             %虛線
>> dottedLineT=[2 3 4];
>> taskNum=9;
>> jobId=[ 2 1 3 3 1 2 2 1 3 ];
>> oper=[ 1 1 2 1 2 3 2 3 3 ];
>> iCriticalPathS=[5 8];            %關鍵路徑
>> iCriticalPathT=[6 9];
>> select=1;

同時繪圖如下:

三、將函數(shù)的.m文件轉換成動態(tài)鏈接庫形式

首先,檢查一下自己的mcc編譯器是否可用

命令行輸入指令

>> !mcc

正常的結果應該如下:

mcc Compile MATLAB functions for deployment outside MATLAB.  
 mcc [-options] fun [fun2...]  
  
 OPTIONS:  
 a    <filename> Add <filename> to the deployable archive. If the specified  
     file is an m, mex or p file, this function will not be exported in the  
     resulting target.  
  
 C    Generate a separate deployable archive.  
  
 d    <directory> Output directory.  
  
 e    Suppress MS-DOS Command Window. Use in place of -m.  
  
 g    Include debugging symbol information.  
  
 I    <path> Add <path> to the list of paths to search for files.  
  
 m    Generate a standalone application.  
  
 N    Clear the compilation search path of all directories except the following  
     core directories:  
         <matlabroot>/toolbox/matlab  
         <matlabroot>/toolbox/local  
         <matlabroot>/toolbox/compiler  
  
 o    <outputfilename> Output name.  
  
 p    <directory>  Add <directory> to the compilation search path. This  
     option can only be used in conjunction with the -N option.  
  
 R    <option> Specify the run-time options for the MATLAB Runtime.  
  
 v    Verbose.  
  
 Y    <license.dat file> Override the default license.dat file.  
  
 EXAMPLES:  
 Make a standalone executable for myfun.m:  
     mcc -m myfun  
  
 Make standalone executable for myfun.m. Look for myfun.m in the  
 directory /files/source, and put the resulting C files and executable in  
 the directory /files/target:  
     mcc -m -I /files/source -d /files/target myfun  
  
 Make a standalone executable from myfun1.m and myfun2.m:  
     mcc -m myfun1 myfun2  
  
For more details, execute "doc mcc" from MATLAB. 

如果出現(xiàn)error,那么就是Matlab的編譯器不能用,原因是Matlab并未完全破解。
解決了編譯器問題之后,之后輸入mbuild -setup

>> mbuild -setup
MBUILD 配置為使用 'Microsoft Visual C++ 2017 (C)' 以進行 C 語言編譯。

要選擇不同的語言,請從以下選項中選擇一種命令:
 mex -setup C++ -client MBUILD 
 mex -setup FORTRAN -client MBUILD

要使用C++編譯器,所以要點擊上面的mex -setup C++ -client MBUILD

之后,在命令行輸入

>> mex -setup
>> mex -setup
MEX 配置為使用 'Microsoft Visual C++ 2017 (C)' 以進行 C 語言編譯。
警告: MATLAB C 和 Fortran API 已更改,現(xiàn)可支持
	包含 2^32-1 個以上元素的 MATLAB 變量。不久以后,
	 您需要更新代碼以利用
	 新的 API。您可以在以下網址找到相關詳細信息:
	 http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html。

要選擇不同的語言,請從以下選項中選擇一種命令:
 mex -setup C++ 
 mex -setup FORTRAN

然后選擇:mex -setup C++

需要注意的是,matlab每次重啟后,都要重新按以上步驟進行mbuild -setup/mex -setup的配置。

選擇Liberty Complier

“TYPE”部分選擇C++ shared Library,“EXPORTED FUNCTIONS”是需要導出的m文件,點擊右側的“Add”按鈕選擇編寫的文件Matlab_Digraph.m。右側是MATLAB運行時庫的安裝打包方式,在本機上測試可選擇“Runtime downloaded from web”。

打包完成后,在項目文件Matlab_Digraph.prj的目錄下生成與項目同名的子目錄,即\Matlab_Digraph,該目錄下有3個文件夾。

Matlab_Digraph\for_redistribution_files_only目錄下是編譯生成的.dll 、.lib和.h文件,其中.lib和.h文件是在Qt項目編譯時需要用到的,.dll文件是程序運行時需要用到的。

將生成的.h.lib.dll文件三個一起拷到代碼所在的文件夾。

可以使用Dependency Walker來查看.dll文件中的一些內容

四、QT調用

1.添加外部庫

點擊下一步,之后按如下配置,點擊瀏覽選擇庫,之后勾掉Linux和Mac,且勾掉為debug版本添加’d’作為后綴。

點擊下一步,你就會發(fā)現(xiàn)你的.pro文件中多了幾行:

win32: LIBS += -L$$PWD/./ -lMatlab_Digraph

INCLUDEPATH += $$PWD/.
DEPENDPATH += $$PWD/.

2.Matlab其他依賴庫和頭文件搜索路徑的加入

重點是Qt 的pro文件的配置,我們需要在pro文件中加入以下內容:

DEFINES += __MW_STDINT_H__

INCLUDEPATH += D:/MATLAB/extern/include
INCLUDEPATH += D:/MATLAB/extern/include/win64

LIBS += -LD:/MATLAB/extern/lib/win64/microsoft -llibmx
LIBS += -LD:/MATLAB/extern/lib/win64/microsoft -llibmat
LIBS += -LD:/MATLAB/extern/lib/win64/microsoft -lmclmcr
LIBS += -LD:/MATLAB/extern/lib/win64/microsoft -lmclmcrrt
LIBS += -LD:/MATLAB/extern/lib/win64/microsoft -llibeng

(這個要根據(jù)自己的Matlab具體的安裝位置來修改。)

3.工程中的頭文件中添加.h文件

#include "Matlab_Digraph.h"

4.系統(tǒng)環(huán)境變量的設置

額外加入的一些庫實際上對應于MATLAB運行時的一些DLL文件,這些運行時文件主要在以下幾個目錄下,所以要保證這些目錄添加到了Windows的環(huán)境變量PATH里。

D:\MATLAB\runtime\win64;
D:\MATLAB\\bin\win64;

若是程序發(fā)布到沒有安裝MATLAB的電腦上,需要用Matlab Compiler編譯生成的安裝包。

5 編寫使用DLL內函數(shù)的代碼

(1)DLL的初始化

Matlab_DigraphInitialize();

在使用Matlab_Digraph.dll里的函數(shù)之前,必須先初始化。Matlab_DigraphInitialize()是庫初始化函數(shù)。

(2)函數(shù)的輸入輸出參數(shù)

mwArray是MATLAB的數(shù)組類,MATLAB編譯生成的DLL的接口函數(shù)的參數(shù)都是采用mwArray類型,例如Matlab_Digraph.h文件中的函數(shù)Matlab_Digraph()的函數(shù)原型為:

extern LIB_Matlab_Digraph_CPP_API void MW_CALL_CONV Matlab_Digraph(const mwArray& fullLineS, const mwArray& fullLineT, const mwArray& v, const mwArray& dottedLineS, const mwArray& dottedLineT, const mwArray& taskNum, const mwArray& jobId, const mwArray& oper, const mwArray& iCriticalPathS, const mwArray& iCriticalPathT, const mwArray& select);

6 mwArray類的使用

四、編譯和運行

void DiGraph::DrawDigraph_CP()
{
	select[0] = 1;
	VectorToArr();
	DrawLines();
	TransFormat();
	c.ImportData_Digraph(in_degree, in_out_weight, MAXVEX, MAXEDGE);
	criticalPathArcSize = c.TransferResults_CP(&iCriticalPathS, &iCriticalPathT);
	if (!Matlab_DigraphInitialize())           // 初始化,必須要使用
	{
		qDebug() << "add init failed.";
		return;
	}
	mwArray in_fullLineS(1, MAXEDGE, mxDOUBLE_CLASS, mxREAL);
	mwArray in_fullLineT(1, MAXEDGE, mxDOUBLE_CLASS, mxREAL);
	mwArray in_jobId(1, taskNum[0], mxDOUBLE_CLASS, mxREAL);
	mwArray in_oper(1, taskNum[0], mxDOUBLE_CLASS, mxREAL);
	mwArray in_v(1, taskNum[0], mxDOUBLE_CLASS, mxREAL);
	mwArray in_dottedLineS(1, MAXEDGE - workPieceNum - taskNum[0], mxDOUBLE_CLASS, mxREAL);
	mwArray in_dottedLineT(1, MAXEDGE - workPieceNum - taskNum[0], mxDOUBLE_CLASS, mxREAL);
	mwArray in_taskNum(1, 1, mxDOUBLE_CLASS, mxREAL);
	mwArray in_iCriticalPathS(1, criticalPathArcSize, mxDOUBLE_CLASS, mxREAL);
	mwArray in_iCriticalPathT(1, criticalPathArcSize, mxDOUBLE_CLASS, mxREAL);
	mwArray in_select(1, 1, mxDOUBLE_CLASS, mxREAL);

	in_fullLineS.SetData(fullLineS, MAXEDGE);
	in_fullLineT.SetData(fullLineT, MAXEDGE);
	in_jobId.SetData(jobId, taskNum[0]);
	in_oper.SetData(oper, taskNum[0]);
	in_v.SetData(macDurationTime, taskNum[0]);
	in_dottedLineS.SetData(dottedLineS, MAXEDGE - workPieceNum - taskNum[0]);
	in_dottedLineT.SetData(dottedLineT, MAXEDGE - workPieceNum - taskNum[0]);
	in_taskNum.SetData(taskNum, 1);
	in_iCriticalPathS.SetData(iCriticalPathS, criticalPathArcSize);
	in_iCriticalPathT.SetData(iCriticalPathT, criticalPathArcSize);
	in_select.SetData(select, 1);

	Matlab_Digraph(in_fullLineS, in_fullLineT, in_v, in_dottedLineS, in_dottedLineT, in_taskNum, in_jobId, in_oper, in_iCriticalPathS, in_iCriticalPathT, in_select);
}

然后構建項目運行,彈出plot繪圖,與預期相符

總結

到此這篇關于QT與MATLAB混合編程的文章就介紹到這了,更多相關QT與MATLAB混合編程內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 隊列的動態(tài)鏈式存儲實現(xiàn)代碼分享

    隊列的動態(tài)鏈式存儲實現(xiàn)代碼分享

    DynaLnkQueue.cpp - 動態(tài)鏈式隊列,即隊列的動態(tài)鏈式存儲實現(xiàn)
    2014-02-02
  • 一篇文章帶你用C語言玩轉結構體

    一篇文章帶你用C語言玩轉結構體

    本文主要介紹C語言 結構體的知識,學習C語言肯定需要學習結構體,這里詳細說明了結構體并附示例代碼,供大家參考學習,有需要的小伙伴可以參考下
    2021-09-09
  • MFC創(chuàng)建右鍵彈出菜單的方法

    MFC創(chuàng)建右鍵彈出菜單的方法

    這篇文章主要介紹了MFC創(chuàng)建右鍵彈出菜單的方法,較為詳細的分析了創(chuàng)建菜單資源及視類添加WM_RBUTTONDOWN消息的實現(xiàn)方法,是非常實用的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-01-01
  • c++將字符串轉數(shù)字的實例方法

    c++將字符串轉數(shù)字的實例方法

    在本篇文章里小編給大家整理的是關于c++將字符串轉數(shù)字的實例方法,有需要的朋友們可以參考下。
    2020-02-02
  • C++中實現(xiàn)fibonacci數(shù)列的幾種方法

    C++中實現(xiàn)fibonacci數(shù)列的幾種方法

    本文主要介紹了C++中實現(xiàn)fibonacci數(shù)列的幾種方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C語言字符串原地壓縮實現(xiàn)方法

    C語言字符串原地壓縮實現(xiàn)方法

    這篇文章主要介紹了C語言字符串原地壓縮實現(xiàn)方法,包含了字符串的遍歷與轉換等操作,是很實用的操作技巧,需要的朋友可以參考下
    2014-09-09
  • 快速學習C語言中for循環(huán)語句的基本使用方法

    快速學習C語言中for循環(huán)語句的基本使用方法

    這篇文章主要簡單介紹了C語言中for循環(huán)語句的基本使用方法,是C語言入門學習中的基礎知識,需要的朋友可以參考下
    2015-11-11
  • 淺談C++左值引用和右值引用

    淺談C++左值引用和右值引用

    這篇文章主要介紹了C++左值引用和右值引用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • C語言實現(xiàn)三子棋源代碼

    C語言實現(xiàn)三子棋源代碼

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)三子棋源代碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • C語言Make命令用法講解

    C語言Make命令用法講解

    本文詳細講解了C語言Make命令用法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01

最新評論