将MATLAB的quadprog函数转化为C++代码在Visual Studio上可运行

一、将Matlab的quadprog函数转为VS可调用的lib及dll链接库

参考文章:VS2008 与 Matlab 的混合编程(quadprog函数为例)_jiabingxi的博客-CSDN博客

主要步骤为:

1.在Matlab中写一个脚本.m文件(这里命名为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

2.在命令行窗口输入

>>mbuild -setup

 

选择“mex -setup C++ -client MBUILD ”后,再在命令行窗口输入>>deploytool,选择Library Compiler,用以生成lib链接库。

 在Library Compiler工具箱生成C++链接库:

 

 点击“Package”直接生成链接库。

3.将生成的链接库文件导入C++工程:

打开VS2019新建一个工程,然后将C_QUADPROG.dll,C_QUADPROG.lib,C_QUADPROG.ctf,C_QUADPROG.h四个文件复制到工程目录下。选择“工具-选项-项目和解决方案-VC++目录”,在“显示以下内容目录”里选择“包含文件”将“F:\MATLAB2022a\extern\include”添加进去,然后选择“库文件”将“F:\MATLAB2022a\extern\lib\win32\microsoft”添加进去,大家可根据自己Matlab实际安装的路径进行修改。

然后选择“项目-属性-配置属性-链接器-输入”,在右边“附加依赖项”一栏填入“C_QUADPROG.lib” 和“mclmcrrt.lib”,其中C_QUADPROG.lib是刚刚用Matlab生成的lib文件,mclmcrrt是调用MATLAB引擎的一个lib文件。

4.将所生成的函数的头文件.h及静态链接库.lib分别部署在头文件与资源文件中:

        (①mclmcrrt.lib位于“F:\MATLAB2022a\extern\lib\win64\microsoft”

        ②调式工程时遇到问题:报错:”Cstring”:未声明的标识符时,查阅资料发现原因:

        CString是MFC中最常见的类之一,用于封装字符串数据结构,需要引入MFC的头文件:

        解决:在main.cpp最上方添加 #include "stdafx.h"  的头文件声明,相应地,在解决方案栏加入stdafx.h的文件)

 5.编写调试的main.cpp:

        在源文件“添加”-->“新建项”,选择C++文件,并命名为main.cpp

 

代码如下: 

#pragma comment(lib, "C_QUADPROG.lib")  //与在属性配置中“添加附加依赖项”的作用相同,前三行可以省去

#pragma comment(lib, "mclmcr.lib")
#pragma comment(lib, "mclmcrrt.lib")

#include <iostream>
#include "stdafx.h"
#include "C_QUADPROG.h"

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;
}

得到的结果:

 二、工程配置时遇到的问题及解决

1.遇到:error LNK2019:无法解析的外部符号... 该符号在函数 _main 中被引用

        原因可能是编译的平台不对,由于目前多数Matlab是基于64位计算机平台,故其生成的函数也适用于64位平台

2.遇到错误:“cout”未声明的标识符 

        ①在声明头文件时加入#include <iostream>的标准输入输出流

        ②在开头添加引号内的内容“using namespace std;"

 3.出现了大量类似“error LNK1104:无法打开文件***.lib”这样的错误,网上说需要添加链接库,添加相应的lib库(在VS的安装路径、MATLAB的安装路径、“C:\Program Files (x86)\Microsoft Visual Studio\Microsoft Visual Studio\VC98\Lib”、“C:VProgram Files (x86)Windows Kits\10\Lib\10.0.19041.0\um\x64”等很多路径添加到“项目属性-->C/C++ --> 附加库目录”)后还是不行,甚至出现“ 缺少“;”,错误计数超过 100;正在停止编译”,原因是在附加库目录里面添加太多的lib路径,在相互调用时出现重复引用、顺序不对等叠加乱码的现象。

解决:

        最后发现在设置包含目录、库目录、附加包含目录等时没有勾选继承选项,勾选上“从父项或项目默认设置继承”就没问题了。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

锅小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值