C++调用MATLAB程序进行混合编程以及常见问题解决

C++调用MATLAB程序方法

编译器版本:VS2017和MATLAB2019a(均为64位)

MATLAB打包生成DLL动态链接库

第一步: 在MATLAB命令行窗口中输入mex -setup,会出现如下界面。
在这里插入图片描述
第二步: 点击界面中的mex -setup C++,出现提示配置VS编译器版本,这里是VS2017。
在这里插入图片描述
第三步: 对MATLAB中的函数进行编译,主要为了生成动态库等文件。

​​​  命令行输入命令:mcc -W cpplib: myadd -T link:lib myadd.m -C

​​​  其中红色字体标出部分为生成动态库名称和matlab中自定义函数名称。
在这里插入图片描述
​​​  输入命令后需要等待几分钟进行编译。生成文件如下:
在这里插入图片描述
​​​  主要文件包括:.dll文件,.h文件,.lib文件和.ctf文件

​​​  至此,在MATLAB平台下进行编译生成库文件的操作就完成了。接下来进行VS2017平台环境配置。

VS2017环境配置

第一步: 在VS中添加MATLAB安装目录下的extern中include文件夹。具体操作为:在VS中右键项目,点击属性,在属性中选择“配置属性”->“VC++目录”->“包含目录”。

示例路径:D:\MATLAB2019\matlab2019\extern\include
在这里插入图片描述
第二步: 在VS中添加需要的lib文件。具体操作为:在VS中右键项目,点击属性,在属性中选择“配置属性”->“VC++目录”->“库目录”。

示例路径:D:\MATLAB2019\matlab2019\extern\lib\win64\microsoft
在这里插入图片描述
第三步: 因为D:\Program Files (x86)\MATLAB 2017a\extern\lib\win64\microsoft这个路径中包含了MATLAB中的数据类型和一些函数的定义文件,如" mclmcrrt.lib"文件等。接下来就是加载lib文件了,lib文件的加载有两种方法:动态加载和静态加载。【本质没有区别,取决于使用习惯】

动态加载: 是指在项目属性的附加依赖项中进行lib的相关操作,使程序能正确加载lib文件。在属性中选择“配置属性”->“链接器”->“附加依赖项”,在其中添加:

libeng.lib
libmat.lib
libmex.lib
libmx.lib
mclmcrrt.lib
mclmcr.lib
myadd.lib(最后这一个是自己生成的那个lib文件)
在这里插入图片描述
静态加载: 是只需要在程序中调用lib文件即可,调用方式如下:

#pragma comment(lib,"myadd.lib")//自己生成的lib文件
#pragma comment(lib,"libeng.lib")
#pragma comment(lib,"libmat.lib")
#pragma comment(lib,"libmex.lib")
#pragma comment(lib,"libmx.lib")
#pragma comment(lib,"mclmcrrt.lib")
#pragma comment(lib,"mclmcr.lib")

程序调用

​​​  程序调用需要注意一些数据类型的处理问题,主要是mwArray类,mwArray是在C++项目中调用MATLAB函数时使用的数据类型,无论传入参数,还是获取返回值,均使用这一种数据类型,可以看作为一种由MATLAB编译器识别的多维数组类型。

这里不做过多的描述,主要可以参考以下内容:
https://blog.csdn.net/yujiao12365/article/details/79533121
https://blog.csdn.net/qq_26464039/article/details/84305030?spm=1001.2014.3001.5501

主程序:

#include "myadd.h"
#include <iostream>
#include <fstream>
#include "mclmcr.h"
#include "matrix.h"
#include "mclcppclass.h"

using namespace std;

#pragma comment(lib,"myadd.lib")//自己生成的lib文件
#pragma comment(lib,"libeng.lib")
#pragma comment(lib,"libmat.lib")
#pragma comment(lib,"libmex.lib")
#pragma comment(lib,"libmx.lib")
#pragma comment(lib,"mclmcrrt.lib")
#pragma comment(lib,"mclmcr.lib")

int main()
{
	myaddInitialize();//初始化函数
	//if (!myaddInitialize()) // 修改为你自己的工程---进行初始化
	//{
	//	cout << "Could not initialize myadd!" << endl;
	//	exit(0);
	//}
	mwArray x(1, 1, mxDOUBLE_CLASS);
	mwArray y(1, 1, mxDOUBLE_CLASS);
	x(1, 1) = 20;
	y(1, 1) = 30;
	mwArray a(1, 1, mxDOUBLE_CLASS);
	mwArray b(1, 1, mxDOUBLE_CLASS);

	myadd(2, a, b, x, y);//修改为你自己的工程---2是返回值的个数,后面跟的a,b存储了返回值,再往后的就是m函数传入的参数
	
	cout << "a = " << a << " b = " << b << endl;

	myaddTerminate();
	system("pause");
	return 0;
}

MATLAB函数:
在这里插入图片描述
成功运行结果:
在这里插入图片描述

常见问题解决

问题1:0x0000000000000000 处有未经处理的异常(在 test2.exe 中): 0xC0000005: 执行位置 0x0000000000000000 时发生访问冲突。
在这里插入图片描述
​​​  这是由于没有对调用的MATLAB函数进行初始化引起的错误,需要在调用MATLAB函数之前进行初始化,在调用结束后由进行关闭。

myaddInitialize();//初始化函数
myaddTerminate();

问题2:0x00007FFEE87C4ED9 处(位于 test2.exe 中)有未经处理的异常: Microsoft C++ 异常: mwException,位于内存位置 0x00000009137EF300 处。
在这里插入图片描述
​​​  这是由于VS工程文件下缺少.ctf文件引发的错误。只需要将生成的.ctf文件添加到工程文件目录即可。

问题3:版本对应问题

​​​  MATLAB与VS需要进行版本对应,这里没有明确指出新老版本的对应关系,因为我的测试是使用MATLAB2019a和VS2017完成的【经测试在VS2013下也可以正常调用】。这里指出的对应是说MATLAB和VS需要同是32位或者64位

​​​  可以在VS下面配置管理器进行选择,以确保版本匹配。
在这里插入图片描述

参考

https://bbs.csdn.net/topics/340106981/
https://blog.csdn.net/weixin_40710375/article/details/87714132
https://blog.csdn.net/qq_26464039/article/details/84305030?spm=1001.2014.3001.5501
https://www.freesion.com/article/84861214838/

书籍:《精通MATLAB与C/C++混合程序设计》
https://pan.baidu.com/s/1xtT7puqoEAoCvEwv83gfmg
提取码:4ku7

  • 0
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值