MATLAB和C\C++混合编程,可以将MATLAB的M文件编译生成 C 代码和 C++ 代码。代码生成目标与 MATLAB 求解器不使用相同的数学核心函数库。因此,C++代码生成解可能不同于MATLAB求解器的解,尤其是对于病态问题。
要求:
参考:https://blog.csdn.net/qq_46467894/article/details/125291664
下载链接:https://sourceforge.net/projects/mingw-w64/files/
参考:https://ww2.mathworks.cn/help/optim/ug/code-generation-for-quadprog-example.html
步骤一:生成matlab的二次规划求解代码。例如:创建C_QUADPROG.m
function X = C_QUADPROG(H,g,A_cons,b_cons,lb,ub)
%C_QUADPROG 输入六个参数,假设没有等式约束,即Aeq = [] 和 beq = []
X = quadprog(H,g,A_cons,b_cons,[],[],lb,ub);
end
步骤二:为m文件生成dll链接库
function X = C_QUADPROG(H,g,A_cons,b_cons,lb,ub)
%C_QUADPROG 输入六个参数,假设没有等式约束,即Aeq = [] 和 beq = []
X = quadprog(H,g,A_cons,b_cons,[],[],lb,ub)
end
参考:https://blog.csdn.net/m0_46427461/article/details/124181300
1、命令行输入:
mbuild -setup
2、选择” mex -setup C++ -client MBUILD “
3、命令行窗口输入>>deploytool,选择Library Compiler
4、添加m文件,运行package进行打包
参考:https://blog.csdn.net/weixin_43450564/article/details/109467939
(1)三者含义
(2)三者关系:
lib文件详解:
如果作为动态链接库的导入库:告诉编译器,调用的函数在哪个dll文件中 —— 起到“桥梁”的作用。
如果作为静态链接库:函数的可执行代码也集成在其中。
导入库和静态库虽然都是以.lib作为结尾的,但是他们的区别很大,他们实质是不一样的东西。
静态库本身就包含了实际执行代码、符号表等;
而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。
lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的。
(1)VS配置项含义
参考:https://blog.csdn.net/weixin_46879188/article/details/121641491
(2)lib h dll VS工程目录配置
参考:https://blog.51cto.com/u_15346415/3671701
https://blog.csdn.net/qq_40462954/article/details/117564908
动态库的调用分为三步曲,建议一个工程后:
隐式调用包括:
教程主要参考: https://blog.csdn.net/m0_46427461/article/details/124181300
报错参考: https://blog.csdn.net/enjoybocai/article/details/105395683
https://blog.csdn.net/weixin_30845171/article/details/98335379
VS2017,创建C++控制台应用。将C_QUADPROG.dll,C_QUADPROG.lib、C_QUADPROG.h3个文件复制到工程目录下。解决方案平台改为X64.
//#pragma comment(lib, "C_QUADPROG.lib") //与在属性配置中“添加附加依赖项”的作用相同,前三行可以省去
//#pragma comment(lib, "mclmcr.lib")
//#pragma comment(lib, "mclmcrrt.lib")
#include
#include "stdafx.h"
#include "C_QUADPROG.h"
#include
using namespace std;
int main()
{
printf("进入main函数");
//初始化DLL动态连接文件
mclmcrInitialize();
// 鉴定Matlab外部调用环境设置是否正确.
if (!mclInitializeApplication(NULL, 0)) {
cout << "error1" << endl;
return -1;
}
C_QUADPROGInitialize();
if (!C_QUADPROGInitialize()) {
cout << "error2" << endl;
return -1;
}
//输入矩阵、数组
double H[3][3] = { {1,-1,1},{-1,2,-2},{1,-2,4} };
double g[3][1] = { {-7},{-12},{-15} };
double A[1][3] = {1, 1, 1};
double b[1] = {1};
double lb[3][1] = { {-10},{-10},{-10} };
double ub[3][1] = { {10},{10},{10} };
//输出矩阵、数组
//double x_out[2];
//double fval_out[1];
//为QUADASSINPROG函数创建输入参数矩阵
mxArray* Input_H = mxCreateDoubleMatrix(3, 3, mxREAL);
//将输入矩阵、数组拷贝至QUADASSINPROG输入参数
memcpy(mxGetPr(Input_H), (void*)H, sizeof(H));
mxArray* Input_g = mxCreateDoubleMatrix(3, 1, mxREAL);
memcpy(mxGetPr(Input_g), (void*)g, sizeof(g));
mxArray* Input_A = mxCreateDoubleMatrix(1, 3, mxREAL);
memcpy(mxGetPr(Input_A), (void*)A, sizeof(A));
mxArray* Input_b = mxCreateDoubleMatrix(1, 1, mxREAL);
memcpy(mxGetPr(Input_b), (void*)b, sizeof(b));
mxArray* Input_lb = mxCreateDoubleMatrix(3, 1, mxREAL);
memcpy(mxGetPr(Input_lb), (void*)lb, sizeof(lb));
mxArray* Input_ub = mxCreateDoubleMatrix(3, 1, mxREAL);
memcpy(mxGetPr(Input_ub), (void*)ub, sizeof(ub));
mxArray* Input[6] = { Input_H, Input_g, Input_A, Input_b, Input_lb, Input_ub };
mxArray* Output[2];
//调用Matlab中的函数 function [x, fval] = QUADASSINPROG(H, C, A, b, lb)以测试
mlxC_QUADPROG( 1, Output, 6, Input);
//为QUADASSINPROG函数创建输出参数指针
mxArray* x = mxCreateDoubleMatrix(1, 3, mxREAL); //输出的x的大小也要随输入矩阵的大小更改
//mxArray* fval = mxCreateDoubleMatrix(1, 1, mxREAL);
//将输出参数传递给输出参数指针
x = Output[0];
//fval = Output[1];
double *x_out = mxGetPr(x); //x_out是DLL开始前定义的double数组;x是DLL开始后定义的mxArray数组
//double *fval_out = mxGetPr(fval);
memcpy(x, mxGetPr(x), sizeof(x));
//memcpy(fval, mxGetPr(fval), sizeof(fval));
CString resultStr;
resultStr.Format("控制量结果:% f % f % f ", x_out[0], x_out[1], x_out[2]);
cout << resultStr << endl;
cout << "结束" << endl;
//char anyKey;
//cin >> anyKey;
C_QUADPROGTerminate(); //结束DLL库
system("pause");
return 0;
}
主要因为工程缺少头文件,在电脑搜索相应的头文件,将缺少的所有头文件全部加入项目中。最后一共添加这么多个头文件。
需要添加头文件#include
同时,需要将“项目-属性-常规”
MFC的使用改为:在共享DLL中使用MFC
公共语言运行时支持:使用多字节字符集
在电脑中检索到mclmcrrt9_11.dll,复制粘贴到工程目录下。
报错信息:
An Error has occurred while trying to initialize the MATLAB Runtime.
The error is: Fatal error loading library C:\Users\zhangzhiwei\source\repos\testmatlab\testmatlab\libmat.dll Error: 找不到指定的模块。
因为电脑上存有多个版本的Matlab系统,将C_QUADPROG.dll 复制到项目目录\x64\Debug文件夹下,运行生成的exe文件,即可。