網站首頁 編程語言 正文
一、封裝matlab函數
首先把matlab代碼封裝成函數形式,下面舉一個例子,myadd是主函數:
function c = myadd(a, b)
c =ADD(a, b);
end
function A = ADD(a, b)
c = a + b;
end
二、 編譯matlab函數
具體編譯步驟為:
1、輸出mex -setup 回車,然后點擊選擇 mex -setup C++;
2、輸入mbuild -setup 回車,然后點擊選擇 mex -setup C++ -client MBUILD;
3、輸入 mcc -W cpplib:addtest -T link:lib myadd.m -C;
(1)-W 是控制編譯之后的封裝格式;
(2)cpplib 是指編譯成 C++ 的 lib,如果需要編譯成 C 的 lib,就用 lib 即可,去掉 cpp;
(3)cpplib 后面的是需要生成文件的文件名,是自己取的,我們取名為 addtest;
(4)-T表示目標,link:lib表示要連接到一個庫文件的目標,目標的名字即是.m函數的名字;
(5)其他具體含義可以通過mcc –help命令查看,注意參數的大小寫
4、編譯完成后會生成:addtest.ctf、addtest.dll、addtest.lib、addtest.h、
addtest.cpp、addtest.def、addtest.exp、addtest.exports 等四個文件,但是在C++ 調用時只用到了前四個:
三 、C++環境配置
說明:創建工程文件,注意:測試環境使用的是64位操作系統,因此務必在x64環境下進行以下配置。(這是與你的matlab版本匹配的,我的matlab安裝的是64bit的)
1、C++目錄
找到自己 Matlab 的安裝目錄按照以下進行配置;
(1)包含目錄:D:\Matlab2020a\extern\include
(2)庫目錄:D:\Matlab2020a\extern\lib\win64\microsoft
說明:如果未安裝matlab,則需要去已安裝過 matlab 的電腦上找到上述兩個路徑所對應的文件
然后將其復制到該電腦,最后將其路徑添加至包含目錄和庫目錄即可!!!
2、鏈接器->輸入->附加依賴項,添加以下庫
mclmcrrt.lib、libmat.lib、libmx.lib、mclmcr.lib、addtest.lib(編譯 matlab 函數時生成的文件);
3、配置系統變量(已修改)
“我的電腦”右鍵,打開“屬性”;選擇“高級系統設置”;找到系統屬性頁面的“高級”選項,右下方
“環境變量”;頁面中下方是系統變量,將如下路徑添加到環境變量的Path中:
(1)如果電腦上裝的有 matlab 則僅需要添加如下路徑:
D:\Matlab2020a\bin\win64
(2)如果電腦上沒有安裝 matlab 則需要添加如下路徑:
劃重點:電腦未安裝matlab是除了要添加上述路徑還需要安裝MCR(matlab編譯環境)具體安裝步驟及說明見:[MCR安裝步驟](https://blog.csdn.net/weixin_47156401/article/details/125181576?spm=1001.2014.3001.5501)
說明:D:\Matlab2020a\runtime\win64 、D:\Matlab2020a\bin、D:\Matlab2020a\polyspace\bin
這三個路徑在安裝 matlab 時系統會自動將其添加到環境變量中,所以如果電腦上未安裝 matlab
則需要去已安裝過 matlab 的電腦上找到上述四個路徑所對應的文件,然后將其復制到該電腦,最后將其路徑添加至環境變量即可!!!
注意:配置完環境變量后需要重啟電腦,環境變量才會生效;
4、重新打開VS2015的項目,將Matlab生成的四個文件放入該項目所在文件夾下(已修改)
說明:需要在Project1\x64\Debug目錄下放入:addtest.dll、addtest.lib、
addtest.ctf,在該目錄下,上述三個文件缺一不可,如果缺少ctf文件,編譯不報錯,初始化會出現內存錯誤
并且添加頭文件addtest.h
5、調試–>窗口–>異常設置–>Win32 Exceptions全部不要勾選
#include "addtest.h"
#pragma comment (lib,"addtest.lib")
int main()
{
//初始化函數必須加
if (!addtestInitialize())
{
cout << "初始化失敗!" << endl;
exit(0);
}
else
cout << "初始化成功!" << endl;
mwArray a(1, 1, mxDOUBLE_CLASS);
mwArray b(1, 1, mxDOUBLE_CLASS);
a(1, 1) = 1.8;
b(1, 1) = 2.9;
mwArray z(1, 1, mxDOUBLE_CLASS);
myadd(1, z, a, b);
std::cout << a << "+" << b << "=" << z << std::endl;
system("pause");
return 0;
}
可能出現的問題:
(1)必須要進行初始化,否則mxarray會報錯。
初始化失敗可能是因為沒有把.ctf放到.dll的同級目錄下
(2)異常:0xc0000005處理
Win32 Exceptions項在vs調試–>窗口–>異常設置 中取消(快捷鍵Ctrl + Alt + E)
四、mwArray數組的運用
1、mwArray的寫入和讀取
網上的通用示例,來展示:
double data[4] = {1.0, 2.0, 3.0, 4.0};
double x;
mwArray a(2, 2, mxDOUBLE_CLASS);
a.SetData(data, 4);
x = a.Get(1,1); // x = 1.0
x = a.Get(2, 1, 2); // x = 3.0
x = a.Get(2, 2, 2); // x = 4.0
解釋一下,用過matlab的同學都知道matlab默認列優先,列優先是什么概念呢?就是數據都是按照列儲存,一列一列在內存上存儲的,這一點C語言也一樣。
也就是說數據是按列存入mwArray結構體,也就是說數據在內存里是存成這樣的:
而我們使用時因為你指定了mwArray a(2, 2, mxDOUBLE_CLASS);嘛,你就可以認為數據就存成了這樣:
x = a.Get(2, 2, 2); // x = 4.0
實際上Get這個函數我真沒看懂,他第一個indice參數是什么意思?指數?嘛,它不重要,真的不重要,我換成了1,2它都好使
后兩個就是索引,你看2行2列是不是4,你再看看1,1列是不是1,但是要注意,2行1列你寫成a.Get(2, 1)它真的不是2,這是因為重載函數默認第一個值是那個不明所以的indice,這就很難受。
我們再來看一個示例,來更加清晰的明白怎么給矩陣賦初值:
int a[6] = {1,2,3,4,5,6}
mwArray A(2,3,mxINT32_CLASS);
A.SetData(a,6); //第二個參數為要設置的數的個數,大小可設為rows*cols
注:該過程相當于把16的矩陣,轉化為23的矩陣,matlab轉化順序是,先排第一列,由上到下為a[0] a[1],然后排第二列,由上到下為a[2] a[3],即轉化后的A為:
1 3 5
2 4 6
如果要使A為:
1 4
2 5
3 6
需這樣賦值:
int a[6] = {1,2,3,4,5,6}
mwArray A(3,2,mxINT32_CLASS); //修改此處:行列數互換
A.SetData(a,6); //第二個參數為要設置的數的個數,大小可設為rows*cols
2、設置輸出
在進行函數運算時我出現了一個問題,就是我的輸出矩陣實際上是數量不確定的,目前沒有在網上找到什么說法,然而通過實驗發現,實際上matlab在輸出時是根據實際矩陣來的,不會出現計算元素數量大于初始設置的元素數量,然后就顯示錯誤的情況。這里進行了一個實驗證明了這個結論:
;
//如何obs為空,將obs替換為mwArray()
SearchingPathPlanning(1, path, outpoint, obs, Rd);
int n = path.NumberOfElements()/ path.NumberOfDimensions();
for (int i = 1; i <=n; i++)
{
std::cout << "a = " << path.Get(1,i,1)<< " b = " << path.Get(2,i, 2) << std::endl;
}
3、注意事項
Mxarray矩陣是標簽是從1開始的,而不是傳統意義上從0開始,比如要進行輸出:
for (int i = 1; i <=7; i++)
{
std::cout << "a = " << outpoint.Get(1,i, 1) << " b = " << outpoint.Get(2,i, 2) << std::endl;
}
原文鏈接:https://blog.csdn.net/plusplusfei/article/details/126509838
相關推薦
- 2022-07-25 C++文件的操作及小實驗示例代碼詳解_C 語言
- 2023-11-20 用python對數據進行擬合求函數表達式的方法
- 2022-02-23 MAC清除所有的mobileprovision
- 2022-09-06 React父組件調用子組件中的方法實例詳解_React
- 2023-02-14 C#實現ComboBox變色的示例代碼_C#教程
- 2023-04-23 Python實現讀取csv文件并進行排序_python
- 2022-07-13 Collection和Collections有什么區別?
- 2022-10-12 python繪制發散型柱狀圖+誤差陰影時間序列圖+雙坐標系時間序列圖+繪制金字塔圖_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支