日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C++的matlab接口轉換方法詳解_C 語言

作者:菜鳥小白進化ing ? 更新時間: 2022-06-01 編程語言

由于matlab的運算速度較慢,因此常常需要使用c++對關鍵部分進行運算。Matlab針對這一需求提供了相應的api方便參數傳遞以及封裝。

這里使用的vs工程,對文件進行修改生成.mexw64文件,對于matlab可識別的文件。

這里的操作都是針對vs進行配置和操作。

一.工程配置

1.配置生成文件

右鍵->屬性->常規->配置類型?動態庫(.dll)

右鍵->屬性->高級->目標文件擴展名?.mexw64

2.配置附加目錄

右鍵->屬性->c++->附加包含目錄? 添加$(Matlab_Dir)\extern\include;?

其中$(Matlab_Dir)為matlab安裝地址

右鍵->屬性->鏈接器->附加庫目錄 添加$(Matlab_Dir)\extern\lib\win64\microsoft;;

其中$(Matlab_Dir)為matlab安裝地址

3.添加附加依賴項

右鍵->屬性->鏈接器->輸入->附加依賴項

輸入libmx.lib;libmex.lib;libmat.lib;libeng.lib;

二.接口編寫

1.添加頭文件

#include "mex.h"是matlab提供的頭文件,利用提供的api進行接口函數編寫

2.接口函數編寫

入口過程的名稱必須是mexFunction,并且包含四個參數

void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]);

nlhs?輸出參數個數,plhs 輸出參數指針?

nrhs 輸入參數個數,prhs 輸入參數指針?

注意:?輸出和輸入參數的操作都是通過指針的方式進行的MATLAB可以通過這些指針,訪問內存中的數據

3.輸入參數獲取

接口過程要把參數傳遞給計算過程,還需要從prhs中讀出矩陣的信息,這就要用到下面的mx-函數和mex-函數。

  • mxGetM(prhs[0]); 獲取其行數
  • mxGetN(prhs[0]);?獲取其列數
  • mxGetNumberOfDimensions(prhs[0]);獲取其維度

主要介紹的是數據獲取的兩個函數?mxGetData?和?mxGetPr。

mxGetData:?返回值為void類型的指針,必須轉換為正確數據類型的指針的指針。

mxGetPr返回值為double類型的指針,可以理解為它會自動轉換?mxGetData的輸出作為double指針。

在使用上這兩種都可以獲取參數內容。

還有一點需要注意的是,無法對未獲取的值進行操作。

下面的代碼在調試時會報錯,無法對于未保存的變量進行操作。

Number = ((double*)mxGetData(mxGetCell(prhs[0], 19)))[0]-1;

4.出錯信息發布函數mexErrMsgTxt,mexWarnMsgTxt

兩函數的具體格式如下:

#include "mex.h"

void mexErrMsgTxt(const char *error_msg);

void mexWarnMsgTxt(const char *warning_msg);

其中error_msg包含了要顯示錯誤信息,warning_msg包含要顯示的警告信息。兩函數的區別在于mexErrMsgTxt顯示出錯信息后即返回到MATLAB,而mexWarnMsgTxt顯示警告信息后繼續執行。

5.輸出參數設置

對于程序的返回結果需要將其保存在plhs指針當中,而且保存在plhs的返回指針類型必須是mxArray。

這里介紹兩個api進行數組,矩陣的創建。由于常用的數據類型為double,這里列舉的均為double類型的數組。

plhs[0] = mxCreateNumericArray(3, dims,mxDOUBLE_CLASS, mxREAL);
plhs[1] = mxCreateDoubleMatrix(n, n, mxREAL);    

6.參數轉置

由于matlab的數據存儲順序與c++不同,因此在數據輸入時需要對數據進行轉換。在數據輸出傳遞的時候,同樣也需要對數組進行轉換。

matlab對于數組存儲是按照列進行保存的,而c++是按照行進行保存,因此在數據計算時需要格外注意。

這里是常用的行列轉換的代碼。

template <class T1, class T2>
void cTranspose3d(T1* dst, T2* src, int srcRow, int srcCol, int channel)
{
	int i = 0, k = 0;
	T1* dst1 = NULL;
	T2* src1 = NULL;
	for (k = 0; k < channel; k++)
	{
		dst1 = dst + k * srcRow * srcCol;
		src1 = src + k * srcRow * srcCol;
		for (i = 0; i < srcRow * srcCol; i++)
		{
			dst1[i] = src1[(i % srcRow) * srcCol + (i / srcRow)];//th/ srcRow//src's  col -> dst's row,th%srcRow//src's   row -> dst's col
		}
	}
}

總結

原文鏈接:https://blog.csdn.net/ltd0924/article/details/123817651

欄目分類
最近更新