1.matlab封装matlab函数
(1)方法一
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;(addtest为封装好的dll名称,myadd为要封装的m文件)
(2)方法二
1、matlab -> APP -> library compiler
2、选择“c++ shared library”,点击“+”加入相应文件
3、点击package(生成addtest.ctf、addtest.dll、addtest.lib、addtest.h等文件)
2.vs调用设置
1、将xxx.lib,xxx.h,xxx.dll,xxx.ctf 文件放入.\project1\project1 文件夹中
2、将xxx.lib,xxx.dll,xxx.ctf 文件放入.\project1\x64\Debug 文件夹中
3、打开VS,将xxx.h导入头文件夹中,将xxx.lib,xxx.dll,xxx.ctf导入资源文件夹中
4、右击项目名称 -> 属性
1)配置属性 -> VC++目录,在包含目录中加入
matlab头文件夹,一般为..\extern\include(根据情况修改)
xxx.h所处文件夹,为.\project1\project1(根据情况修改)
2)配置属性 -> VC++目录,在库目录中加入
matlab lib文件夹,一般为..\extern\lib\win64\microsoft(根据情况修改)
xxx.lib所处文件夹,为 .\project1\x64\Debug(根据情况修改)
3)配置属性 -> 链接器 -> 输入,在附加依赖项中加入
mclmcrrt.lib、mclmcr.lib、libmat.lib、libmx.lib、libmex.lib、libeng.lib、xxx.lib
5、点击调试 -> 窗口 -> 异常设置,取消勾选Win32 Exceptions(空为取消)
注:matlab的环境变量需要自己设置: .\Matlab2020a\bin\win64(根据情况修改)
3.代码调用
1、引入头文件
#include "xxx.h"
#pragma comment(lib, "xxx.lib")
//将xxx修改为自己的.h,.lib名
2、初始化
if ((!mclInitializeApplication(NULL, 0)) || (!MyAddInitialize()))
{
cout << "Could not initialize the application"<<endl;//初始化失败
}
else
{
cout << "Initializing Success!!!" << endl;//初始化成功
}
注:“MyAddInitialize” 中的“ MyAdd ” 需要改为自己dll的名称
3、定义mArray
mwArray a(1, 1, mxDOUBLE_CLASS); //函数参数类型为mwArray, 大小为1*1,数据类型为double
mwArray b(1, 1, mxDOUBLE_CLASS); //函数参数类型为mwArray, 大小为1*1,数据类型为double
mwArray c(2, 4, mxDOUBLE_CLASS); //函数参数类型为mwArray, 大小为2*4,数据类型为double
4.初始化mArray
1)初始化方法一
a(1, 1) = 1.8; //初始化参数
2)初始化方法二
double aa = 1.0;
a.SetData(&aa, 1);//a中有几个数就为几
3)初始化方法三
//想传递矩阵的方法
double cc[8] = { 1,2,3,4,5,6,7,8 };
c.SetData(cc, 8);//初始化参数
//传入后的矩阵为
// 1 3 5 7
// 2 4 6 8
//竖着传递
注:其他mArray传递参数方法:将c++的变量赋值给matlab的mwArray数据类型
5、调用matlab函数
1)方法一(直接调用)
//直接调用
kk(1, z, a, b);
//参数分别为(返回值个数、接收返回值的mArray、输入变量mArray数组1、输入变量mArray数组2)
//kk为matlab中的函数名
2)方法二(显示调用)
//显示调用
//先在主函数前声明
typedef void(*testFunc)(int nargout, mwArray& u,const mwArray& f1,const mwArray& f2);
/***********************************************************************************/
//再在函数内调用
HINSTANCE hDll = LoadLibrary(L"xxx.dll");//xxx改为之前生成的dll名称
testFunc kk= (testFunc)GetProcAddress(hDll, "zzzzzzzz");//根据自己的修改
if (!kk)
{
cout << "Error" << endl;
}
kk(1, c, a, b);
注:上述代码中的“zzzzzzzz”,需要自己查找修改
[1] 先查看dll中包含的函数名,查看方法:用VS附带工具来查看dll文件包含的函数
[2] 将其中的matlab中的函数名修改后的函数名找出,替换上述代码的“zzzzzzzz”
(如上图,将 “zzzzzzzz” 替换为 ”_Z5MyAddiR7mwArrayRKS_S2_”)
我matlab中的函数名为MyAdd,不知道为什么matlab中的函数名打包成dll后会变成这样,但修改后可以使用。
注:函数前声明的输入参量也要修改
6、获取函数返回值
double z = c.Get(1, 1);
7、结束
MyAddTerminate();
mclTerminateApplication();
FreeLibrary(hDll);
system("pause");
注:“MyAddTerminate” 中的“ MyAdd ” 需要改为自己dll的名称
4.完整代码
#include "MyAdd.h"
#pragma comment(lib, "MyAdd.lib")
#include <iostream>
using namespace std;
typedef void(*testFunc)(int nargout, mwArray& aa, const mwArray& Flag1, const mwArray& Flag2);
int main()
{
if ((!mclInitializeApplication(NULL, 0)) || (!MyAddInitialize()))
{
cout << "Could not initialize the application" << endl;//初始化失败
}
else
{
cout << "Initializing Success!!!" << endl;//初始化成功
}
mwArray a(1, 1, mxDOUBLE_CLASS); //函数参数类型为mwArray, 大小为1*1,数据类型为double
mwArray b(1, 1, mxDOUBLE_CLASS);
mwArray c(1, 1, mxDOUBLE_CLASS);
a(1, 1) = 2.9;//初始化方法一
double bb = 0.1;
b.SetData(&bb, 1);//初始化方法二
//显示调用
HINSTANCE hDll = LoadLibrary(L"MyAdd.dll");
testFunc kk = (testFunc)GetProcAddress(hDll, "_Z5MyAddiR7mwArrayRKS_S2_");
if (!kk)
{
cout << "Error" << endl;
}
kk(1, c, a, b);
//获取结果
double z = c.Get(1, 1);
cout << a << "+" << b << "=" << z << endl;
//结束
MyAddTerminate();
mclTerminateApplication();
FreeLibrary(hDll);
system("pause");
return 0;
}
参考博客:C++中调用matlab的dll文件(解决初始化失败的问题)_zy_ky的博客-CSDN博客
该博客意在记笔记,纯属为了以后使用方便!!!