VS与Matlab混合编译 - mexw64 (C++版)
版權聲明:本文為博主原創文章,未經博主允許不得轉載。https://blog.csdn.net/wwwoowww/article/details/83013801
?
這幾天遇見一個項目,需要在matlab中調用c/c++ 代碼。在matlab中直接使用mex編輯各種不方便,網上都是使用c mex在vs下編程,滿足不了我的需求,幸好在在matlab官網發現提供了基于面向對象的使用方法,對比使用c mex編程的特點是:
C++ MEX functions are based on two C++ APIs:
-
The MATLAB Data API supports MATLAB data types and optimizations like copy-on-write for data arrays passed to MEX functions. For more information.
-
A subset of the MATLAB C++ Engine API supports calling MATLAB functions, execution of statements in the MATLAB workspace, and access to variables and objects. For more information.
也就是:第一次調用創建了對象,在之后的調用中,對象的狀態都是持續存在的。每次的調用會使用相同的對象,能夠保存一些狀態~~
利用提供的API 還能在c++中調用matlab中的函數(feval(....)方法)~~~
官網介紹 c++ mex編程:https://ww2.mathworks.cn/help/matlab/matlab_external/c-mex-functions.html
c++ mex API :?https://ww2.mathworks.cn/help/matlab/matlab_external/cpp-mex-api.html#mw_43f0bbf9-b23e-4b59-87cf-eb770b5e6cb9
?
在這里把在VS下的開發流程貼出,以便大家參考。
環境:win10,VS2017,MatlabR2018a。
?
1.創建項目
? ? VS2017沒有了win32選項,直接選擇控制臺應用程序就行。
2.添加依賴項
? ?進入項目的屬性頁,在自己的項目中右鍵-》屬性。找到 配置屬性 底下的 VC++ 目錄。
? ?注意:我的是matlab提供的lib文件64位的,請在平臺 x64 下編輯一下所有。
2.1我們需要在 VC++目錄 設置 包含目錄,庫目錄
?
? (1)包含目錄: 添加Matlab安裝目錄下的 ...\extern\include,我的是 D:\Matlab2018a\extern\include
?
? (2) 添加 庫目錄: Matlab安裝目錄下的 ...\extern\lib\win64\microsoft ;?我的是?D:\Matlab2018a\extern\lib\win64\microsoft
?
2.2 添加 鏈接器 信息
? ?選擇 鏈接器-》輸入-》附加依賴項—》添加一下
? ? libmex.lib
? ? libMatlabDataArray.lib
?
2.3 修改輸出文件為dll 。把配置類型改為dll
? ? 點擊應用,保存以上修改。
?
3.在文件中添加代碼段(來源于matlab官網 https://ww2.mathworks.cn/help/matlab/matlab_external/c-mex-source-file.html,稍后解釋)
matlab默認傳入的數據類型為double,
/* MyMEXFunction* Adds second input to each * element of first input* a = MyMEXFunction(a,b); */#include "pch.h" #include "mex.hpp" #include "mexAdapter.hpp"using namespace matlab::data; using matlab::mex::ArgumentList;class MexFunction : public matlab::mex::Function { public:void operator()(ArgumentList outputs, ArgumentList inputs) {checkArguments(outputs, inputs);const double offSet = inputs[0][0];TypedArray<double> doubleArray = std::move(inputs[1]);for (auto& elem : doubleArray) {elem += offSet;}outputs[0] = doubleArray;}//檢查輸入參數格式void checkArguments(ArgumentList outputs, ArgumentList inputs) {// Get pointer to enginestd::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();// Get array factoryArrayFactory factory;// Check first input argumentif (inputs[0].getType() != ArrayType::DOUBLE ||inputs[0].getType() == ArrayType::COMPLEX_DOUBLE ||inputs[0].getNumberOfElements() != 1){matlabPtr->feval(u"warning",0,std::vector<Array>({ factory.createScalar("First input must scalar double") }));}// Check second input argumentif (inputs[1].getType() != ArrayType::DOUBLE ||inputs[1].getType() == ArrayType::COMPLEX_DOUBLE){matlabPtr->feval(u"fprintf",0,std::vector<Array>({ factory.createScalar("Input must double array") }));}// Check number of outputsif (outputs.size() > 1) {matlabPtr->feval(u"error",0,std::vector<Array>({ factory.createScalar("Only one output is returned") }));}} };代碼解釋:
#include "mex.hpp" #include "mexAdapter.hpp"class MexFunction : public matlab::mex::Function { public:void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {//TODO// 我們的代碼添加在這兒...} };類名必須是MexFunction,matlab會調用operator() 方法,我們在其中中添加自己的代碼就行。如果改了名字,matlab就找不到了對象了。
outputs,inputs 分別是matlab調用中的輸入和輸出參數。
如何創建outputs 見:?https://blog.csdn.net/wwwoowww/article/details/83111371
?
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();// Get array factory ArrayFactory factory;// Check first input argument if (inputs[0].getType() != ArrayType::DOUBLE ||inputs[0].getType() == ArrayType::COMPLEX_DOUBLE ||inputs[0].getNumberOfElements() != 1) {matlabPtr->feval(u"error",0,std::vector<Array>({ factory.createScalar("First input must scalar double") })); }matlabPtr提供了多種方法,其中?matlabPtr->feval(u"error",0,std::vector<Array>({ factory.createScalar("First input must scalar double") })); 是調用了matlab中的error方法。
具體的參數及用法還是見https://ww2.mathworks.cn/help/matlab/matlab_external/cpp-mex-api.html#mw_43f0bbf9-b23e-4b59-87cf-eb770b5e6cb9
?
生成dll
? ?注意 要選擇 x64, 點擊生成->生成解決方案。
?
輸出成功:
?
4.將生成的dll文件(matlab_c_plus.dll拷貝到matlab的目錄下,并改后綴dll為mexw64)
調用方法: 文件名()? 也就是 matlab_c_plus(1,2)
如下圖調用成功~~~
總結
以上是生活随笔為你收集整理的VS与Matlab混合编译 - mexw64 (C++版)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 双系统引导修复与引导项删除
- 下一篇: windows-vscode编写c/c+