C/C++教程

C++调用Matlab生成的DLL动态链接库进行混合编程(VS2010+Matlab2012a)

本文主要是介绍C++调用Matlab生成的DLL动态链接库进行混合编程(VS2010+Matlab2012a),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Matlab在处理图像时进行数据分析时具有很大的优势,由于与企业对接时一般需要用到其他编程语言,如C++等,因此可以将Matlab函数编译成dll文件,可以在C++中对其进行调用。初次使用时会出现许多错误,并且很多错误都没法通过编译器的提示进行修改,本文将详述使用的整个过程并把几乎所有可能遇到的错误罗列出来,希望对读者有所帮助。

文章目录

    • 实验环境
    • 1、前期环境配置工作
    • 2、32位Matlab安装
    • 3、Matlab编译动态链接库
    • 4、配置VS2010
    • 5、测试
    • 可能遇到的问题
    • 补充
    • 参考链接

实验环境

  • 操作系统:WindowsXP
  • C++ IDE:Visual Studio 2010
  • Matlab版本:Matlab 2012a

1、前期环境配置工作

本文的方法针对所有版本的Visual Studio+Matlab均适用,关键要确保所使用的C++编译器能被当前使用的Matlab所支持,查看各版本Matlab所支持编译器
在这里插入图片描述

由于工作对接需要使用的是Microsoft Visual C++ 2010 Professional,这里找到只有MatlabR2012往后的老版本还支持VS2010,点击Detail可以看到
在这里插入图片描述

2、32位Matlab安装

由于使用的操作系统为WindowsXP,是一个32位的操作系统,在安装上与Matlab只有一点细微的差别。网上下载的安装包一般是32位/64位放在一起的一个安装包,而安装教程给的只有64位的安装教程,其实我们只要找到对应的32位的setup.exe按照64位的方法同样安装即可。
一般点开解压后的安装包可以看到
在这里插入图片描述

我们需要点开同目录下的bin文件夹,可以看到win32以及win64文件夹,里边分别存放32位和64位的安装程序,我们选择所需的win32打开即可,使用win32目录下的setup.exe按照64位安装教程进行即可完成32位的Matlab安装。

在这里插入图片描述
在这里插入图片描述
安装好后打开Matlab我们可以在Command窗口输入mexext可以查看到
在这里插入图片描述
返回mexw32表示当前Matlab是支持生成win32的动态链接库的,64位对应为mexw64。

3、Matlab编译动态链接库

第一步:在matlab的命令行窗口中输入mex -setup,会出现以下界面(旧版本),新版本会列出当前系统所存在的所有编译器,点击选择即可。

在这里插入图片描述

第二步:在Matlab中创建一个图像处理函数

function fun_imshow(path)
I=imread(path);
I1=rgb2gray(I);
[Can,~]=edge(I1,'canny');
imshow(Can);
end

第三步:对matlab的函数进行编译。**注意:这里只能对matlab的function进行编译,并不能对一般的.m脚本进行编译。

这里采用的mcc命令有两种方式:

1.mcc -W cpplib:fun_imshow -T link:lib fun_imshow.m -C
2.mcc -W cpplib:fun_imshow -T link:lib fun_imshow.m

第一种方式会把Matlab所用到的工具箱单独生成一个.ctf文件,需要把.ctf文件与.dll文件一同放到所生成的.exe文件目录下;第二种方式不会单独编译出.ctf文件来,只需要把.dll文件放到.exe文件目录下即可。我们采用的是第二种方式,生成文件如下所示:

在这里插入图片描述

我们需要用到的文件只有fun_imshow.dll,fun_imshow.h,fun_imshow.lib这三个。

4、配置VS2010

第一步:新建一个空项目,添加一个新的源文件,输入一个简单的main()函数预生成一次,此时会在工程目录下多出一个Debug文件夹。

注意:我们所使用的是32位的Matlab,对应需要在Win32下进行Debug

在这里插入图片描述

第二步:将fun_imshow.h,fun_imshow.lib复制到.cpp文件的同目录下,fun_imshow.dll复制到Debug目录下(注意:可能工程目录下会有多个Debug目录,应复制到生成.exe的Debug目录下)

第三步:右键工程文件,选择Properties → \rightarrow →VC++ Directories

  • Include Directories:matlabroot\extern\include
  • Library Directories:matlabroot\extern\lib\win32\microsoft

matlabroot为本机Matlab的安装目录。

在这里插入图片描述

第四步:Properties → \rightarrow →Linker → \rightarrow →Input

Additional Dependencies:mclmcrrt.lib,libmat.lib,libmx.lib

在这里插入图片描述

至此完成VS2010调用Matlab库的环境配置。

5、测试

提供以下测试程序

#include "fun_imshow.h"
#include <iostream>
#pragma comment(lib, "fun_imshow.lib")

using namespace std;

int main()
{
	bool isOk = 0;//判断动态库是否初始化成功
    if (!mclInitializeApplication(NULL, 0))
    {
        cout << "Could not initialize the application.\n";
        return -1;
    }
    cout << "isOk = " << isOk << endl;// 0
    isOk = fun_imshowInitialize(); // 动态库初始化成功
    cout << "isOk = " << isOk << endl;// 1
	//system("pause");
	fun_imshow("C:/Users/Admin/Desktop/aaa.jpg"); //调用matlab函数
    mclWaitForFiguresToDie(NULL);  //等待图像显示,不加此句无法显示图像
    fun_imshowTerminate();  //关闭动态库
    mclTerminateApplication();
    return 0;
}

只要修改fun_imshow()函数的图片输入路径即可输出图片显示结果。

可能遇到的问题

  1. 找不到mclmcrrtx_xx.dll

在这里插入图片描述

mclmcrrtx_xx.dll是位于Matlab安装目录下tuntime文件夹里的一个文件,我们正常安装后是具有这一个文件的,并且程序编译时可以通过我们的path环境变量去找到这一个文件。首先去查看电脑的path环境变量是否含有这一个文件的路径,如果没有,将这一个文件的文件夹路径添加进去,重启电脑。一般情况下,安装完Matlab后会自动给我们添加进去,如果我们是首次安装完后就进行编译,系统依然是无法找到这个文件的,需要重启电脑。

在这里插入图片描述

  1. 0xC0000005: 读取位置 0x00000000 时发生访问冲突

在这里插入图片描述

这个错误是在使用64位编译环境时会抛出的一个异常,因为我们此时使用的是一个64位Matlab编译出来的dll文件,Win32无法兼容。此时程序是可以编译成功,但无法执行。我们只需要按Ctrl+Alt+E(或Debug → \rightarrow →Exceptions)取消Win32 Exceptions勾选即可。

补充

C++数组数据转换成Matlab可读取的图片数据格式(参考刘维的《精通Matlab与C/C++混合程序设计》)

提供测试程序如下

function fun_imshow(I)
imshow(I);
end
#include "fun_imshow.h"
#include <iostream>
#include <vector>

#pragma comment(lib, "fun_imshow.lib")

using namespace std;

int main()
{
	const int rows = 1000;
	const int columns = 1000;
	double* a;
	a = new double[rows*columns];
	for(int i=0; i<rows*columns;i++){
			a[i] = 0;
	}
	bool isOk = 0;//判断动态库是否初始化成功
    if (!mclInitializeApplication(NULL, 0))
    {
        cout << "Could not initialize the application.\n";
        return -1;
    }
    cout << "isOk = " << isOk << endl;// 0
    isOk = fun_imshowInitialize(); // 动态库初始化成功
    cout << "isOk = " << isOk << endl;// 1
	system("pause");
	mwArray data(columns,rows,mxDOUBLE_CLASS);
	data.SetData(a,rows*columns);
	delete a;
	fun_imshow(data); //调用matlab函数
    mclWaitForFiguresToDie(NULL);  //等待图像显示,不加此句无法显示图像
    fun_imshowTerminate();  //关闭动态库
    mclTerminateApplication();
    return 0;
}

实现任何形式图片数据通过调用Matlab生成的dll进行处理显示,只要实现图片数据类型向mwArraw类型转换即可。
注意:Matlab数据读取的方式是按列读取的

参考链接

Link1
Link2
Link3

这篇关于C++调用Matlab生成的DLL动态链接库进行混合编程(VS2010+Matlab2012a)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!