一、Matlab生成动态链接库DLL
前提:电脑中有C/C++编译器(例如VS)
1、在matlab中打开需要生成的文件 “文件名.m”
例如Main.m;
2、在下方命令行中输入
mex -setup
选择使用C/C++的compiler;
3、再输入
mbuild -setup
选择使用C/C++的builder,注意与上一致;
4、生成动态链接库DLL
输入
mcc -W lib:动态链接库名称 -T link:lib 文件名.m
生成C的DLL;
输入
mcc -W cpplib:动态链接库名称 -T link:lib 文件名.m
生成C++的DLL;
5、生成下列文件(我的动态链接库名称为mydll)
【注意】符号计算(例如syms)/神经网络工具包都不能在打包后被调用
建议改写为数值计算。
二、配置VS2017
1、新建一个控制台project,将上述生成的文件复制到这个工程文件夹下面;
3、Matlab与VS的位数一致(都是x86或者x64)
若Matlab是x64,而VS是x86,则会报错:
警告 LNK4272 库计算机类型“x64”与目标计算机类型“x86”冲突
修改VS到x64的方法如下:
(1)右侧解决方案中,右击,“属性->链接器->高级->目标计算机”设置为"MachineX64 (/MACHINE:X64)";
(2)“属性->链接器->命令行->其他选项”设置为" /machine:X64 /debug ";
(3)“生成->配置管理器->活动解决方案平台”勾选两个对应于“Win32”(x64)的选项;
(4)“生成->配置管理器->活动解决方案平台”设置为" X64 "。
3、添加路径
(1)右侧解决方案中,右击,“属性->VC++目录->包含目录”,编辑添加
...自己补全安装目录\MATLABr2018a\extern\lib\win64\microsoft
(2)“属性->VC++目录->库目录”,编辑添加
...自己补全安装目录\MATLABr2018a\extern\include
(3)“属性->链接器->输入->附加依赖项”
mydll.lib
mclmcrrt.lib
(4)如果提示“mclmcrrt.h”不存在
在安装目录\MATLABr2018a\extern\lib\win64\microsoft中找到这个文件,然后复制到在工程下的自己新建lib文件夹,“属性->VC++目录->引用目录”,编辑添加这个lib文件夹。
(5)在“我的电脑->系统变量->path”
添加 matlab到win64的路径,例如:
E:\MATLABr2018a\bin\win64
三、运行DLL
VS主函数main的简单框架如下:
#include "stdafx.h"
#include "mydll.h"
int main()
{
mydllInitialize(); //初始化DLL动态连接文件
mxArray *input[1]; //将输入参数传递进去,根据自己需要补充代码设置
mxArray *output[1]; //定义输出参数指针
mlxMain(1, output, 1, input); //调用m函数,即mlx+.m中的函数名
mydllTerminate(); //结束DLL库
}
函数的对应改写方法可以参考:https://ww2.mathworks.cn/help/compiler_sdk/cxx/matlab-compiler-generated-interface-functions.html
如果编译成功但是F5运行时抛出异常:
********处(位于dlltest.exe 中)引发的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突
Ctrl+Alt+E取消Win32 Exceptions
或者在vs2017界面-->调试-->异常设置-->取消勾选Win32 Exceptions
四、参数变量定义与函数调用
参数有两种格式,对应于调用的函数的两种格式,具体可以看mydll.h代码文件
(1)
bool MW_CALL_CONV mlx函数名(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);
VS中调用的函数是“mlx函数名”,参数列表分别是:输入参数个数,输入参数,输出参数个数,输出参数。
mxArray* 参数1 = mxCreateString("your string");//string
(2)
extern LIB_mydll_CPP_API void MW_CALL_CONV 函数名(const mwArray& 参数1, const mwArray& 参数2);
VS中调用的函数是“函数名”,参数列表分别是:输入参数1,输出参数2。
mwArray 参数1 = "your string";//string
mwArray 参数2(true);//bool
五、抄送一个Demo
matlab:
function b = MyFunc(a)
b = a.*a;
生成:
mcc –W cpplib:mydll –T link:lib MyFunc.m –C
VS2017:
// dlltest.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "mydll.h"
using namespace std;
int main()
{
cout << "start" << endl;
if (mydllInitialize()) //必须的要初始化,格式为 名字Initialize()
{
cout << "success" << endl;
}
else
{
cout << "fail" << endl;
return 0;
}
//mydllInitialize(); //初始化DLL动态连接文件
system("pause");
double _x[5] = { 1,2,3,4,5 }; //输入数组
double _y[5]; //输出数组
mxArray* x = mxCreateDoubleMatrix(1, 5, mxREAL); //创建1*5矩阵
memcpy(mxGetPr(x), (void*)_x, sizeof(_x)); //拷贝输入数据
mxArray *input[1] = { x }; //将矩阵x的指针作为输入参数传递进去
mxArray *output[1]; //定义输出参数指针
mlxMyFunc(1, output, 1, input); //调用m函数
mxArray *y; //定义输出结果指针
y = output[0]; //将输出参数传递给输出结果
memcpy(_y, mxGetPr(y), sizeof(_y)); //拷贝输出数据
mydllTerminate(); //结束DLL库
//显示数组中的数据
string str;
cout << _y[0] << endl;
cout << _y[1] << endl;
cout << _y[2] << endl;
cout << _y[3] << endl;
cout << _y[4] << endl;
system("pause");
}
运行结果:
六、参考来源
https://blog.csdn.net/wcq1973/article/details/51177614