C++调用matlab编译动态库方法及相关问题解决

news2024/12/24 2:09:05

目录

  • 参考链接:
  • 1、C++调用matlab代码的方法
    • 1.1、Library Compiler 方法
      • 1.1.1、功能
      • 1.1.2、参考链接
    • 1.2、mex -setup方法
      • 1.2.1、功能
      • 参考链接:
    • 1.3、coder 方法
      • 功能
    • 1.4、Matlab engine
  • 2、C++ 使用matlab编译动态库的传参方法
  • 3、matlab运行时

参考链接:

matlab与C/C++混合编程——在Windows/Linux上调用Matlab编译的动态库文件

1、C++调用matlab代码的方法

1.1、Library Compiler 方法

1.1.1、功能

把matlab代码编译成动态库,C++调用matlab生成的动态库

1.1.2、参考链接

C++ Dll导出及python调用C++ DLL

1.2、mex -setup方法

1.2.1、功能

把matlab代码编译成动态库,C++调用matlab生成的动态库。除了可以生成动态库,还能生成调试信息.pdb文件,chatgpt回答的方法如下,还没有进行测试

参考链接:

C++调用MATLAB函数
C/C++程序通过动态链接库调用MATLAB程序

在这里插入图片描述

1.3、coder 方法

功能

把*.m代码编译成C++代码,但是对于有些m代码中使用了有些库文件、调用了非m代码的函数的函数是无法编译成C++源代码。

参考链接:
如何使用MATLAB coder将MATLAB代码转换成C/C++语言(详细图文教程)

启动方法:在运行框中键入“coder”,便会打开MATLAB coder界面

1.4、Matlab engine

下面测试样例是打开一张图片,成为cv::Mat格式使用matlab引擎(engine.h)加载到matlab进行显示,主要熟悉Matlab engine的使用方式

#include "string.h"
#include "opencv.hpp"

#include <engine.h>

using namespace std;
int MatlabDisplayImg_Gray(cv::Mat SrcMat);//matlab显示灰度图


int main_Dis(int argc, char* argv[])
{
//先处理非matlab代码
	const char* SrcImg = argv[2];
	cv::Mat SrcMat = cv::imread(SrcImg, cv::IMREAD_COLOR);

	return MatlabDisplayImg_Gray(SrcMat);
	//return MatlabDisplayImg_RGB(SrcMat);//彩色图片显示有问题,就不粘贴进来了


}


int MatlabDisplayImg_Gray(cv::Mat SrcMat)
{
	cv::cvtColor(SrcMat, SrcMat, cv::COLOR_BGR2GRAY);


	// 引擎初始化
	Engine* eng = engOpen(nullptr);
	if (eng == nullptr)
	{
		std::cerr << "Cannot open MATLAB Engine" << std::endl;
		return EXIT_FAILURE;
	}

	// 初始化mclmcr,如果没有这两句可能会有访问错误的问题
	mclmcrInitialize();
	if (!mclInitializeApplication(NULL, 0))
	{
		return -1;
	}
	printf("Success Initialize mclmcr!\n");


	//把Mat传入到matlab中进行显示代码
	const mwSize TempDims[2] = { SrcMat.rows, SrcMat.cols };
	mxArray* imgArray = mxCreateNumericArray(2, TempDims, mxDOUBLE_CLASS, mxREAL);

	double* pData = mxGetPr(imgArray);
	//unsigned char* pData = mxGetPr(im1);
	for (int i = 0; i < SrcMat.rows; ++i)
	{
		for (int j = 0; j < SrcMat.cols; ++j)
		{
			pData[j*SrcMat.rows + i] = SrcMat.at<uchar>(i, j);
		}
	}
	//将数组传递给Matlab中,变量名为im1
	engPutVariable(eng, "im1", imgArray);
	//执行Matlab命令,读取img并显示
	engEvalString(eng, "figure,imshow(uint8(im1))");//传入进去是double* 类型,必须转换成uint8类型才能正常显示
	//释放内存
	mxDestroyArray(imgArray);
	engClose(eng);
}


2、C++ 使用matlab编译动态库的传参方法

1.下面演示一个从外部传参,传入3个const char* 作为mxArray* 对象


#include "RIFT2_Match_MatLab.h"
#include<vector>

void ToMatlabCharArray(const char* myString, mxArray*& myCharArray)
{

	// 获取字符串长度并加 1,以便在字符串末尾添加结束标志符 \0
	size_t stringLength = strlen(myString);

	// 使用 mxCreateCharArray 函数创建 mxArray 类型变量
	mwSize dims[2] = { 1, static_cast<mwSize>(stringLength ) };
	myCharArray = mxCreateCharArray(2, dims);

	 使用 mxSetData 将 char* 类型的数据指针赋值给 mxArray 类型变量,下面这种赋值方式有问题,乱码
	//mxSetData(myCharArray, charArrayBuffer);


	// 将字符数组复制到mxArray*对象中
	mxChar* data = mxGetChars(myCharArray); // 获取mxArray*对象的数据缓冲区指针
	for (int i = 0; i < stringLength; ++i)
	{
		data[i] = myString[i];
	}

	return ;
}

int main(int argc, char* argv[])//_Test
{
	printf("Matlab RIFT2_Match,V1.0 zph");
	
	const char* SrcImg = argv[1];
	const char* DstImg = argv[2];
	const char* ptsFile = argv[3];


	// 初始化mclmcr,如果没有这两句可能会有访问错误的问题
	mclmcrInitialize();
	if (!mclInitializeApplication(NULL, 0))
	{
		return -1;
	}
	printf("Success Initialize mclmcr!\n");
	//初始化应用
	//if (!myplotInitialize())
	if (!RIFT2_Match_MatLabInitialize())
	{
		return -1;
	}
	printf("Success Initialize doMatch!\n");


	mxArray* SrcImgCharArray = nullptr;
	ToMatlabCharArray(SrcImg, SrcImgCharArray);

	mxArray* DstImgCharArray = nullptr;
	ToMatlabCharArray(DstImg, DstImgCharArray);

	mxArray* PtsCharArray = nullptr;
	ToMatlabCharArray(ptsFile, PtsCharArray);
	printf("data  Initialized!\n");
	//调用主函数
	mlfRIFT2_Match_MatLab(SrcImgCharArray, DstImgCharArray, PtsCharArray);
	printf("Match done!\n");


	// 关闭应用
	RIFT2_Match_MatLabTerminate();
	return 0;
}

2.下面演示把一个cv::Mat单通道影像传入进去


///*

#include "string.h"
#include "doMatch.h"
#include "opencv.hpp"

#include <engine.h>


int main(int argc,char* argv[])//_Test
{

	 引擎初始化
	//Engine* eng = engOpen(nullptr);
	//if (eng == nullptr)
	//{
	//	std::cerr << "Cannot open MATLAB Engine" << std::endl;
	//	return EXIT_FAILURE;
	//}

	const char* SrcImg = argv[1];
	const char* DstImg = argv[2];
	cv::Mat SrcMat = cv::imread(SrcImg);
	cv::Mat DstMat = cv::imread(DstImg);
	

	cv::cvtColor(SrcMat,SrcMat,cv::COLOR_BGR2GRAY);
	cv::cvtColor(DstMat,DstMat,cv::COLOR_BGR2GRAY);


	// 初始化mclmcr,如果没有这两句可能会有访问错误的问题
	mclmcrInitialize();
	if (!mclInitializeApplication(NULL, 0))
	{
		return -1;
	}
	printf("Success Initialize mclmcr!\n");
	//初始化应用
	//if (!myplotInitialize())
	if (!doMatchInitialize())
	{
		return -1;
	}
	printf("Success Initialize doMatch!\n");

	mxArray **cleanedPoints1 = nullptr;
	mxArray **cleanedPoints2 = nullptr;
	
	//SrcMat
	const mwSize SrcDims[2] = { SrcMat.rows, SrcMat.cols };
	mxArray* SrcImgArray = mxCreateNumericArray(2, SrcDims, mxDOUBLE_CLASS, mxREAL);
	double* SrcpData = mxGetPr(SrcImgArray);
	for (int i = 0; i < SrcMat.rows; ++i)
	{
		for (int j = 0; j < SrcMat.cols; ++j)
		{
			SrcpData[j*SrcMat.rows + i] = SrcMat.at<uchar>(i, j);
		}
	}
	//Dst
	const mwSize DstDims[2] = { DstMat.rows, DstMat.cols };
	mxArray* DstImgArray = mxCreateNumericArray(2, DstDims, mxDOUBLE_CLASS, mxREAL);
	double* DstpData = mxGetPr(DstImgArray);
	for (int i = 0; i < DstMat.rows; ++i)
	{
		for (int j = 0; j < DstMat.cols; ++j)
		{
			SrcpData[j*DstMat.rows + i] = DstMat.at<uchar>(i, j);
		}
	}



	printf("data  Initialized!\n");
	//调用主函数
	mlfDoMatch(2, cleanedPoints1, cleanedPoints2, SrcImgArray, DstImgArray);
	printf("Match done!\n");
	

	// 关闭应用
	doMatchTerminate();
	//system("pause");

	return 0;
}


//*/

3、matlab运行时

说明:在使用matlab编译的exe或者dll,移植到一个没有matlab的电脑时可能无法运行,需要在官网上下载对应的运行时进行安装后,程序才能正常执行。
matlab运行时官网下载:
https://www.mathworks.com/products/compiler/matlab-runtime.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/465786.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《AI嵌入式系统技术与实践-基于树莓派RP2040和MicroPython》书籍介绍

图书封面及出版信息 该书由本博主编著&#xff0c;全书总字数约50万字&#xff0c;本书于2023年4月出版。 内容简介 本书基于以RP2040 MCU芯片为核心的树莓派Pico开发板硬件扩展接口&#xff0c;利用Pico硬件扩展接口和面包板设计典型硬件电路&#xff0c;并结合当今流行的微…

网络编程(TCP与UDP协议)

文章目录 1. 网络编程1.1 软件架构1.2 网络基础 2. 网络通信要素2.1 如何实现网络中的主机互相通信2.2 通信要素一&#xff1a;IP地址和域名2.2.1 IP地址2.2.2 域名 2.3 通信要素二&#xff1a;端口号2.4 通信要素三&#xff1a;网络通信协议 3. 传输层协议&#xff1a;TCP与UD…

如何快速查询Git的config配置文件的本地路径

如何快速查询Git的config配置文件的本地路径 命令作用git config --local --list --show-origin查看仓库级别 git 配置信息&#xff0c;并打印配置文件本地路径最高优先级&#xff08;仓库下&#xff09;git config --global --list --show-origin查看全局级别 git 配置信息&a…

2022年全国职业院校技能大赛网络系统管理赛项模块B:Windows部署(样题1)

2022年全国职业院校技能大赛 网络系统管理赛项 模块B&#xff1a;Windows部署 &#xff08;样题1&#xff09; 目录 一、 初始化环境 &#xff08;一&#xff09;默认账号及默认密码 二、项目任务描述 &#xff08;一&#xff09;基本配置 &#xff08;二&#xff09;拓…

C语言控制语句

文章目录 前言一、分支语句1.if语句2.if else else if3.switch语句 二、循环语句1.for循环2.while循环3.do-while循环 三、跳转语句1.break语句2.continue语句3.goto语句 四、嵌套语句1.if语句嵌套2.for语句嵌套3.while语句嵌套 总结 前言 C语言中的控制语句是非常重要的一个知…

JVM入门必备

1、JVM 的位置 2、JVM 的体系结构 JVM&#xff08;Java虚拟机&#xff09;是Java程序的运行环境&#xff0c;它对于Java平台的运行和跨平台特性的实现有着重要的作用。JVM的体系结构有以下几个部分&#xff1a; 类加载器&#xff08;ClassLoader&#xff09;&#xff1a;负责将…

day4 IP地址与端口号

IP地址及其表示方式 IP地址表示方法&#xff1a; 分类的IP地址&#xff1a; 多归属主机&#xff1a; 当一个主机通过两个网卡同时连接到两网络时&#xff0c;也就是该主机同时拥有两个IP地址&#xff0c;该主机被称为多归属主机&#xff1b; 一个路由器至少连接到两个不同的网…

C++语法(21)---- 模拟map和set

(1条消息) C语法&#xff08;20&#xff09;---- 模拟红黑树_哈里沃克的博客-CSDN博客https://blog.csdn.net/m0_63488627/article/details/130296772?spm1001.2014.3001.5501 目录 1.stl中的设计思想 2.模拟set和map 1.set和map的类 2.BRTree的仿函数实现 3.红黑树的迭…

C语言力扣简单题-两数之和

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 两数之和 题目&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和…

从数据处理到人工智能(常用库的介绍)

Python库之数据分析 ​​​​​​​​​​​​ 可以这么理解pandas通过扩展了对一维数据和二维数据的一种表示&#xff0c;因而能够形成更高层对数据的操作&#xff0c;简化数据分析的运行 Python库之数据可视化 Matplotlib — Visualization with Python seaborn: statistic…

DNS基础:通过dig命令理解DNS域名解析中的A记录,AAAA记录,CNAME记录,MX记录,NS记录

参考博文&#xff1a;https://blog.csdn.net/zxl1990_ok/article/details/125432123 目录 参考资料DNS简介查询过程直接显示DNS寻址结果向特定DNS服务器寻址查询A记录查询AAAA记录CNAME记录MX记录NS记录PTR记录SOA记录查看DNS服务器的主从关系 参考资料 http://ruanyifeng.com…

C++ Primer阅读笔记--异常处理机制

目录 1--异常处理机制 2--throw表达式 3--try语句块 4--标准异常类 5--代码实例 1--异常处理机制 异常处理机制为程序中的异常检测和异常处理这两部分的协作提供支持&#xff1b;在 C 语言中&#xff0c;异常处理包括&#xff1a;throw表达式、try语句块和异常类&#xff…

线程池【Linux】

文章目录 1. 引入2. 应用3. 实现封装线程封装线程池线程函数生产消费逻辑互斥锁条件变量线程函数主线程测试1 4. 优化5. 日志日志的重要性实现日志级别提取参数stdarg.h 头文件日志文件 懒汉实现单例模式什么是懒汉模式什么是单例模式实现 1. 引入 线程池是一种池化技术&#…

Vue后台管理系统-前端登录设计

在做后台管理系统时&#xff0c;登录模块是必不可少的&#xff0c;访模块看似简单&#xff0c;在开发涉及到许多细节&#xff0c;一般来说主要有以下这些&#xff1a; 1. 登录输入的信息要进行正则校验&#xff1b; 2. 密码输入要可以查看明文&#xff1b; 3. 密码输入时要对…

JavaWeb——IP协议的相关特性

目录 一、IP协议 1、地址管理 &#xff08;1&#xff09;、动态分配IP地址 &#xff08;2&#xff09;、NAT机制 &#xff08;3&#xff09;、IPv6协议 2、路由选择 &#xff08;1&#xff09;、定义 &#xff08;2&#xff09;、原理 二、路由器 三、IP地址的组成 1…

Postman登录注册指导

在做后端开发的小伙伴经常需要测试自己写的接口是否可以用 这时Postman就是一个很好的选择 如果您还没有下载 可以参考我的文章 API接口调试工具Postman下载安装步骤 安装好之后 我们就需要处理 它的一个注册和登录 我们点击右上角 这里就有一个创建一个账户 我们点击一下 …

CF - Playing in a Casino

题意&#xff1a;一个数的幸运值计算规则是用里面最大的数字-最小的数字所得值 给出一个范围&#xff0c;求这个范围里幸运值最大的是哪个数 解&#xff1a; 这道题相对来说就很简单了&#xff0c;注意数值限制范围在1道1e6&#xff0c;虽然这道题确实暴力就能做出来&#xf…

手把手教你用几行代码给winform多个控件(数量无上限)赋值

前言&#xff1a; 我们在开发winform程序的过程中&#xff0c;经常会遇到这样一个场景&#xff0c;我们设计的界面&#xff0c;比如主窗体有一百多个TextBox&#xff0c;然后初始化的时候要对这个一百多个TextBox的Text属性赋值&#xff0c;比如赋个1&#xff0c;如果是winfor…

CAD DLL 15 crack增加了对SLDASM、FSAT

CAD DLL 15 crack增加了对SLDASM、FSAT 改进的3D&#xff1a; 提高了打开三维文件的速度。 提高了SAT、STEP、SLDPRT、X_T、X_B、OBJ格式的阅读能力。 增加了对SLDASM、FSAT、SAB、SMT、IPT、IFC格式的支持。 增加了导出为SAT、SAB、STL、OBJ格式的功能。 改进了SAT、STE…

系统错误 无法启动此程序,因为计算机中丢失MSVCP140_1.dll。尝试重新安装该程序已解决此问题

Qt系列文章目录 文章目录 Qt系列文章目录前言一、解决方法 前言 我在windows10系统&#xff0c;使用Qt5.15.2 打包命令&#xff1a;windeployqt.exe ImageManageSys.exe &#xff0c;把ImageManageSys.exe 拷贝到windows7系统下&#xff0c;报错&#xff1a;ImageManageSys.ex…