精华内容
下载资源
问答
  • MATLAB与C++/MFC混合编程;调用MATLAB函数因为项目需要,前期工作一直在VS2013(编译平台Win32)与MATLAB2014a(64bit)两个平台进行,...但是发现C++处理数据远没有MATLAB方便,便开始百度“C++/MFC调用MATLAB函数”,惊

    MATLAB与C++/MFC混合编程;调用MATLAB函数

    因为项目需要,前期工作一直在VS2013(编译平台Win32)与MATLAB2014a(64bit)两个平台进行,VS2013用来生成数据,MATLAB2014a用来处理数据,为了简化过程便于应用,想将MATLAB的数据处理程序移植成C++代码,但是发现C++处理数据远没有MATLAB方便,便开始百度“C++/MFC调用MATLAB函数”,惊奇发现原来还有MATLAB与C++混合编程这么回事。但是按照网上教程配置环境始终不能成功,搞了好几天,逛论坛、找人请教才终于解决。
    _**本文先参考网上教程配置编程环境,再针对我遇到的问题给出解决方案。**
    
    1.MATLAB环境配置
    打开MATLAB,在命令行输入:mex -setup,回车,选择已安装的vc编译器
    

    这里写图片描述

    依次点击mex -setup C++ 和Microsoft Visual C++ 2013 Professional(根据自己情况)后看到以下提示:
    

    这里写图片描述
    然后继续在命令行中输入:mbuild -setup ,按照上述类似的方式设置编译器。

    2. 新建m文件
    建议从简单函数入手,这样会容易找到后续编译不成功的问题。
    
        function C=Add(A,B)
                    C=A+B;
        end
    保存为Add.m文件。
    
    3. 创建动态链接库
    Matlab命令行中输入:mcc -W cpplib:libAdd -T link:lib Add
    回车后出现错误提示:**Test checkout of feature 'Compiler' failed**,百度后知道是MATLAB破解不完全,于是找了个matlab R2014a fully crack,破解MATLAB编译器。重启后继续输入上面的命令,等待编译完成。
    

    这里写图片描述

    将.h、.lib、.dll文件拷贝到VS工程目录下。
    
    4. 系统环境配置
    Computer - > Properties -> Advanced system settings -> Environment Variables -> User Variables -> path, 添加("MATLAB"为MATLAB 2014a软件安装目录)
    

    …\MATLAB\extern\lib\win32\microsoft;
    …\MATLAB\bin\win32
    Computer - > Properties -> Advanced system settings -> Environment Variables -> System Variables -> path, 添加
    …\MATLAB\runtime\win32;
    …\MATLAB\bin;
    …\MATLAB\bin\win32
    …\MATLAB\extern\lib\win32\microsoft;

    5.VS2013环境配置
    

    这里写图片描述

    这里写图片描述

    这里写图片描述

    这里写图片描述

    这里写图片描述

    libeng.lib
    libmat.lib
    libmex.lib
    libmx.lib
    mclmcrrt.lib
    mclmcr.lib
    libAdd.lib(最后这一个是Add.m生成的)  
    6. VS2013下编写MFC程序并测试
    

    
    #include "stdafx.h"
    #include "TestMatlab.h"
    #include "TestMatlabDlg.h"
    #include "afxdialogex.h"
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include "mclmcr.h"
    #include "matrix.h"
    #include "mclcppclass.h"
    #include "libAdd.h"
    using namespace std;
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    
    // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
    
    class CAboutDlg : public CDialogEx
    {
    public:
        CAboutDlg();
    
    // 对话框数据
        enum { IDD = IDD_ABOUTBOX };
    
        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    
    // 实现
    protected:
        DECLARE_MESSAGE_MAP()
    };
    
    CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
    {
    }
    
    void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialogEx::DoDataExchange(pDX);
    }
    
    BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
    END_MESSAGE_MAP()
    
    
    // CTestMatlabDlg 对话框
    
    
    
    CTestMatlabDlg::CTestMatlabDlg(CWnd* pParent /*=NULL*/)
        : CDialogEx(CTestMatlabDlg::IDD, pParent)
    {
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
    
    void CTestMatlabDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialogEx::DoDataExchange(pDX);
        DDX_Control(pDX, IDC_RESULT_EDIT, m_calcResult);
    }
    
    BEGIN_MESSAGE_MAP(CTestMatlabDlg, CDialogEx)
        ON_WM_SYSCOMMAND()
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_BN_CLICKED(IDC_CALCULATE_BUTTON, &CTestMatlabDlg::OnBnClickedCalculateButton)
    END_MESSAGE_MAP()
    
    
    // CTestMatlabDlg 消息处理程序
    
    BOOL CTestMatlabDlg::OnInitDialog()
    {
        CDialogEx::OnInitDialog();
    
        // 将“关于...”菜单项添加到系统菜单中。
    
        // IDM_ABOUTBOX 必须在系统命令范围内。
        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
        ASSERT(IDM_ABOUTBOX < 0xF000);
    
        CMenu* pSysMenu = GetSystemMenu(FALSE);
        if (pSysMenu != NULL)
        {
            BOOL bNameValid;
            CString strAboutMenu;
            bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
            ASSERT(bNameValid);
            if (!strAboutMenu.IsEmpty())
            {
                pSysMenu->AppendMenu(MF_SEPARATOR);
                pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
            }
        }
    
        // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
        //  执行此操作
        SetIcon(m_hIcon, TRUE);         // 设置大图标
        SetIcon(m_hIcon, FALSE);        // 设置小图标
    
        // TODO:  在此添加额外的初始化代码
    
        return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
    }
    
    void CTestMatlabDlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
        if ((nID & 0xFFF0) == IDM_ABOUTBOX)
        {
            CAboutDlg dlgAbout;
            dlgAbout.DoModal();
        }
        else
        {
            CDialogEx::OnSysCommand(nID, lParam);
        }
    }
    
    // 如果向对话框添加最小化按钮,则需要下面的代码
    //  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
    //  这将由框架自动完成。
    
    void CTestMatlabDlg::OnPaint()
    {
        if (IsIconic())
        {
            CPaintDC dc(this); // 用于绘制的设备上下文
    
            SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
    
            // 使图标在工作区矩形中居中
            int cxIcon = GetSystemMetrics(SM_CXICON);
            int cyIcon = GetSystemMetrics(SM_CYICON);
            CRect rect;
            GetClientRect(&rect);
            int x = (rect.Width() - cxIcon + 1) / 2;
            int y = (rect.Height() - cyIcon + 1) / 2;
    
            // 绘制图标
            dc.DrawIcon(x, y, m_hIcon);
        }
        else
        {
            CDialogEx::OnPaint();
        }
    }
    
    //当用户拖动最小化窗口时系统调用此函数取得光标
    //显示。
    HCURSOR CTestMatlabDlg::OnQueryDragIcon()
    {
        return static_cast<HCURSOR>(m_hIcon);
    }
    
    
    
    void CTestMatlabDlg::OnBnClickedCalculateButton()
    {
        // TODO:  在此添加控件通知处理程序代码
        double a = 6;
        double b = 9;
        double c;
        // initialize lib,这里必须做初始化!
        if (!libAddInitialize())
        {
            MessageBox(_T("Could not initialize libMyAdd!"));       
        }
        // 为变量分配内存空间,可以查帮助mwArray
        mwArray mwA(1, 1, mxDOUBLE_CLASS); // 1,1表示矩阵的大小(所有maltab只有一种变量,就是矩阵,为了和Cpp变量接轨,设置成1*1的矩阵,mxDOUBLE_CLASS表示变量的精度)
        mwArray mwB(1, 1, mxDOUBLE_CLASS);
        mwArray mwC(1, 1, mxDOUBLE_CLASS);
        // set data,调用类里面的SetData函数给类赋值
        mwA.SetData(&a, 1);
        mwB.SetData(&b, 1);
        // using my add,掉我自己写的函数
        Add(1, mwC, mwA, mwB);
        // get data,调用类里面的Get函数获取取函数返回值
        c = mwC.Get(1, 1);
        CString str;
        str.Format(_T("%.5f"), c);
        SetDlgItemText(IDC_RESULT_EDIT, str);
        // 后面是一些终止调用的程序
        // terminate the lib
        libAddTerminate();
        // terminate MCR
        //mclTerminateApplication();
    }
    
     将MATLAB编译生成的.h文件添加到头文件里,编译生成解决方案时提示错误:error LNK2019: 无法解析的外部符号 _ref_count_obj_addref,该符号在函数 "protected: __thiscall mwArray::mwArray(class array_ref *,bool)" (??0mwArray@@IAE@PAVarray_ref@@_N@Z) 中被引用 
    
        1>TestMatlabDlg.obj : error LNK2019: 无法解析的外部符号 _ref_count_obj_addref,该符号在函数 "protected: __thiscall mwArray::mwArray(class array_ref *,bool)" (??0mwArray@@IAE@PAVarray_ref@@_N@Z) 中被引用
    
    
    1>TestMatlabDlg.obj : error LNK2019: 无法解析的外部符号 _array_ref_getV_int,该符号在函数 "public: class mwArray __cdecl mwArray::GetPromoted(unsigned int,...)" (?GetPromoted@mwArray@@QAA?AV1@IZZ) 中被引用
    
    1>TestMatlabDlg.obj : error LNK2019: 无法解析的外部符号 _array_ref_get_numeric_mxDouble,该符号在函数 "public: __thiscall mwArray::operator double(void)const " (??BmwArray@@QBENXZ) 中被引用
    
    1>TestMatlabDlg.obj : error LNK2019: 无法解析的外部符号 _array_ref_set_numeric_mxDouble,该符号在函数 "public: void __thiscall mwArray::SetData(double *,unsigned int)" (?SetData@mwArray@@QAEXPANI@Z) 中被引用
    
    1>TestMatlabDlg.obj : error LNK2019: 无法解析的外部符号 _error_info_get_message,该符号在函数 "public: virtual char const * __thiscall mwException::what(void)const " (?what@mwException@@UBEPBDXZ) 中被引用
    
    1>TestMatlabDlg.obj : error LNK2019: 无法解析的外部符号 _mclcppGetLastError,该符号在函数 "public: static void __cdecl mwException::raise_error(void)" (?raise_error@mwException@@SAXXZ) 中被引用
    
    1>TestMatlabDlg.obj : error LNK2019: 无法解析的外部符号 _mclcppCreateError,该符号在函数 "public: __thiscall mwException::mwException(class error_info *,bool)" (??0mwException@@QAE@PAVerror_info@@_N@Z) 中被引用
    
    1>TestMatlabDlg.obj : error LNK2019: 无法解析的外部符号 _mclGetMatrix,该符号在函数 "public: __thiscall mwArray::mwArray(unsigned int,unsigned int,enum mxClassID,enum mxComplexity)" (??0mwArray@@QAE@IIW4mxClassID@@W4mxComplexity@@@Z) 中被引用
    
    1>TestMatlabDlg.obj : error LNK2019: 无法解析的外部符号 _libAddInitialize,该符号在函数 "public: void __thiscall CTestMatlabDlg::OnBnClickedCalculateButton(void)" (?OnBnClickedCalculateButton@CTestMatlabDlg@@QAEXXZ) 中被引用
    
    1>TestMatlabDlg.obj : error LNK2019: 无法解析的外部符号 _libAddTerminate,该符号在函数 "public: void __thiscall CTestMatlabDlg::OnBnClickedCalculateButton(void)" (?OnBnClickedCalculateButton@CTestMatlabDlg@@QAEXXZ) 中被引用
    
    1>TestMatlabDlg.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) void __cdecl Add(int,class mwArray &,class mwArray const &,class mwArray const &)" (__imp_?Add@@YAXHAAVmwArray@@ABV1@1@Z),该符号在函数 "public: void __thiscall CTestMatlabDlg::OnBnClickedCalculateButton(void)" (?OnBnClickedCalculateButton@CTestMatlabDlg@@QAEXXZ) 中被引用
    
    1>D:\A_DATA\Learning_OpenCV\VS_learning_opencv\TestMatlab副本\Debug\TestMatlab.exe : fatal error LNK1120: 12 个无法解析的外部命令
     **解决方案:1.VS2013的编译平台换成X64
             2.安装32位MATLAB2014a**
    

    这里写图片描

    附:如果有问题请留言描述问题,或留下QQ

    展开全文
  • 本项目采用win7 64位系统、VS2010和matlab2014a制作,项目展示了VS2010调用matlab库函数的方法。如果是32位系统可以参考我的博客,修改包含路径以及找到win32使用的dll即可。
  • C++调用matlab函数

    2019-10-01 17:57:36
    C++与matlab混合编程——C++调用MATLAB函数 笔者最近在从事一个MFC相关的项目,要求将用Matlab实现的算法通过应用MFC制作成一个小应用。其中有一部分内容需要求一个多元函数的最值。通过网络,我找到了两个C++优化...

    C++与matlab混合编程——C++调用MATLAB函数

           笔者最近在从事一个MFC相关的项目,要求将用Matlab实现的算法通过应用MFC制作成一个小应用。其中有一部分内容需要求一个多元函数的最值。通过网络,我找到了两个C++优化库,dlib与MIDACO_Project ,可是这两个库中的优化函数的应用方式无法融入MFC编程框架,因此想到应用matlab与C++混合编程来实现相关计算。在网络上查了很多资料使问题得到了解决,下面对之前所查资料的内容做一番总结。

    一、编译matlab函数

          在matlab命令行输入窗口中输入“mex -setup”命令,打开对mex的配置选项,根据自己电脑上的配置,会显示出matlab自带的lcc-win32编译器和其它C编译器。我电脑是32位的,matlab版本为R2014a,C编译器为Visual studio2013的编译器。如下图所示,已经显示了我电脑上的两种编译器,在此可用鼠标点击选择“Microsoft Visual C++ 2013 Professional (c)”选项,有的版本的matlab会提示在命令行中输入字符来进行选择。有两种情况是matlab中无法显示其它的编译器选项:1、如果matlab先于visual studio安装的话,输入“mex -setup”命令,matlab里面会没法显示visual studio编译器,很简单的解决方法就是重新装一次visual studio保证其在matlab之后安装到电脑上;2、当前matlab版本无法支持电脑上的编译器,比如:matlab2014版本的就无法支持VS2015。在这个网站上有各个版本的matlab对编译器的支持情况,根据网站内的说明来下载对应的编译器。

     

           接下来就要在matlab中创建需要被编译的函数了,很多网站内的例子都是一些很简单的函数,比如:两个数的求和,害得我一度认为只能够将一些较为简单的函数进行编译。我所写的函数如下图所示,其中的内容较为复杂,应用到了matlab中的@关键字来获取函数,并且在objrmse函数中还调用了很多其它的函数,将这个函数所调用的所有m文件放到当前目录下。

           在命令行输入窗口中输入“mcc -W cpplib:WPCtriForTwo  -T link:lib WPCtriForTwo.m”,其中前一个WPCtriForTwo是生成的库名,可以自己指定,WPCtriForTwo.m为需要被编译的,matlab函数文件。稍等一会,就可以完成对函数的编译,并且在当前目录中生成很多编译后的文件,需要用到的文件有三个:后缀名分别为:WPCtriForTwo.h,WPCtriForTwo.dll,WPCtriForTwo.lib。将这三个文件复制到项目中来,其中后缀名为dll的文件要放入MFC项目的debug目录中,后缀名为h的文件需要添加到项目中去,通过右击项目选择“添加”->“现有项”,从文件管理器中选择该文件放入项目中。由于在项目中会应用到很多从matlab编译过来的函数,我项目中建立一个文件夹matlabFunctionLib来放置编译生成的lib文件,并且将WPCtriForTwo.lib文件放进去。

    二、配置MFC项目

           将matlab程序编译为C++程序后,还需要很多matlab所提供的C++库的支持,这些库及其相应的头文件都放在了MATLBA的安装目录下的extern目录中。考虑到并不是每台电脑上都安装有matlab,因此我选择将这些内容复制到MFC项目中,通过相对路径的方式对这些内容进行引用。将“matlab安装目录/extern”目录中的include目录和lib目录一并复制到MFC项目中,如图内红框所示。

     

    接下来设置项目对上述内容(包括通过编译生成的和从matlab中复制过来的)的引用。

           右击打开项目的属性窗口,选中VC++目录选项,我们需要修改其中的包含目录和库目录两部分的内容,如下图所示。在"包含目录"中应用相对路径语法(注意:在VS中相对的是后缀名为vcxproj文件的路径)添加之前从matlab中复制加入的include目录,即添加一条“../include”信息。在"库目录"中添加之前从matlab中复制过来的lib目录中的相关库文件的目录,由于所设置的MFC项目为32位的,所以需要添加包含32位库的目录,因此编辑添加“..lib\win32\microsoft”。

      选中“链接器”->“常规”->"附加库目录",在其中添加matlabFunctionLib目录的相对位置,这样项目编译时就可以找到所matlab函数编译所生成的库文件。

     

      最后,在“链接器”->“输入”->"附加依赖项"中,输入如下内容:

    mclmcrrt.lib
    libmx.lib
    libmat.lib
    libeng.lib
    WPCtriForTwo.lib

      其中WPCtriForTwo.lib为编译生成的lib文件,其余的几个为matlab中所带的lib文件。这样就完成了混合编程的VS配置工作。

    三、C++对所编译的matlab函数进行调用

      在需要调用函数的文件中添加包含,对于我的项目就是#include “WPCtriForTwo.h”。可以参考这一篇博客中的例子来学习如何调用matlab函数。

     

    转载于:https://www.cnblogs.com/AlgrithmsRookie/p/7049467.html

    展开全文
  • 说明:本文中以调用MATLAB绘图为例,且本工程只能在MFC Release x64下运行,若想在x86下运行,需下载32位MATLAB,重新编译配置工程等等。 两大步骤: 在MATLAB中编写自定义函数,并编译成VS能调用的文件(.lib .dll...

    环境:VS2017、MATLAB2018b 64bit、  win10 64bit

    语言:C++

    说明:本文中以调用MATLAB绘图为例,且本工程只能在MFC Release x64下运行,若想在x86下运行,需下载32位MATLAB,重新编译配置工程等等。

    两大步骤:

    • 在MATLAB中编写自定义函数,并编译成VS能调用的文件(.lib .dll .h等)
    • 在VS中新建MFC工程调

    一、在MATLAB中编写自定义函数,并编译成VS能调用的文件(.lib .dll .h等)

    1. 编写自定义函数,注意函数名和文件名要一相同,rec是返回参数,固定为10,演示使用,无意义。

    2. 确认编写无误后再保存:编写好后,注释掉第一句和最后一句,去掉第二三行的注释。(编写好后最好是先验证MATLAB程序是否能正常运行,否则在MFC中运行到此函数后会停止运行或者显示不出想要的结果

    3. 将MATLAB程序恢复到第一步并保存

    4. 编译MATLAB程序

    在MATLAB命令行中输入mex -setup, 出现如下提示:

    因为我需要用VS2017调用,理论上我应该选用下面框选的,但是看后面的路径似乎不对(还没试过直接选择这一条命令对不对,可自行试试,语言要选择C++)

    再查看了Microsoft Visual C++ 2015 (C)路径下的文件,有支持VS2017的

    所以在命令行输入mex -setup:D:\Matlab2018b\2018b\bin\win64\mexopts\msvc2017.xml C++此条命令是复制了VS2015的路径,然后将2015改为2017,C改为C++,出现如下提示

    然后再输入mcc -W cpplib:draw -T link:lib test.m,其中draw是编译后生成的相关文件名,test.m是自己写的MATLAB程序的文件名,函数名仍为test,输入后,稍等数十秒

    出现如上提示表示成功,再查看.m文件夹下出现了我们需要的文件

    二、在VS中新建MFC工程调

    1.新建一个MFC单文档工程,并添加菜单栏按钮,再为其添加相应的处理函数

    2. 配置工程

    打开“项目-》xxx属性-》VC++目录-》包含目录”添加MATLAB安装文件夹下的"\extern\include"

    打开“项目-》xxx属性-》VC++目录-》库目录”添加MATLAB安装文件夹下的"\extern\lib\win64\microsoft"

    打开“项目-》xxx属性-》链接器-》输入”添加libmat.lib libeng.lib libmx.lib mclmcrrt.lib draw.lib

    然后将MATLAB程序编译后的如下四个文件添加到MFC工程目录下,其中draw.ctf在V2目录下

    然后在要调用此函数的Cpp文件里添加 draw.h 和 math.h,到此就可以成功编译MFC工程

    3. 在新添加的菜单栏按钮处理函数中添加相应的调用代码(注意函数参数除了第一个为int类型,表示返回参数的个数,其余参数都是mwArray类型,需要转换)

    void CMainFrame::Ontest()
    {
    	// TODO: 在此添加命令处理程序代码
    	if (Open_Soft == 0)//打开软件后只需要初始化一次
    	{
    		if (!mclInitializeApplication(NULL, 0))
    		{
    			AfxMessageBox(_T("Could not initialize !"));
    			return;
    		}
    		Open_Soft++;
    	}
    	if (!drawInitialize())//文件名+Initialize构成
    	{
    		AfxMessageBox(_T("Could not initialize !"));
    		return;
    	}
    	返回参数/
    	mwArray sum;
    	生成横坐标数据///
    	double xx[80];//横坐标
    	for (int i = 0; i < 80; i++)
    	{
    		xx[i] = -4 + 0.1*i;
    	}
    	mwArray x(80, 1, mxDOUBLE_CLASS, mxREAL);//80*1的矩阵
    	x.SetData(xx, 80);//将xx数组的值赋值给矩阵x,80是xx的长度
    	生成纵坐标数据///
    	double yy[80];//纵坐标
    	for (int j = 0; j < 80; j++)
    	{
    		yy[j] = sin(xx[j]);
    	}
    	mwArray y(80, 1, mxDOUBLE_CLASS, mxREAL);
    	y.SetData(yy, 80);
    	/调用绘图//
    	test(1, sum, x, y);//调用
    	/获取返回参数,此处返回参数是一个1*1的矩阵///
    	int sum_rec[1];
    	sum.GetData(sum_rec, 1);
    	CString rec; rec.Format(_T("返回参数为:rec = %d"), sum_rec[0]);
    	AfxMessageBox(rec);
    	//结束调用///
    	drawTerminate();
    }

    最后编译运行此工程后,在VS界面右下角取消Win32 Exception的勾选

    结果如图:返回参数正确,曲线正确(点击下图中确定后,会结束调用,图像会消失,如果不想图片自动消失,可将上面程序中最后一行注释掉://drawTerminate();)

    百度云盘链接:https://pan.baidu.com/s/1OfJxvYYtxlyBcmpop_wQ0Q
    提取码:j0np 

    CSDN下载链接:https://download.csdn.net/download/weixin_41303441/12048635

    展开全文
  • matlab函数编译成库,供C++调用(亲测成功) 应用背景: 最近有个图像计算,还带着机台控制的任务要计划。想着怎么实现的问题。对于图像数据的处理,MATLAB具有着很高的计算性能,一些算法用MATLAB很容易实现,...

    matlab函数编译成库,供C++调用(亲测成功)

    应用背景:

    最近有个图像计算,还带着机台控制的任务要计划。想着怎么实现的问题。对于图像数据的处理,MATLAB具有着很高的计算性能,一些算法用MATLAB很容易实现,但是界面用MATLAB开发的现在参考较少。而用C++做控制界面容易。但是图像计算很复杂。

    然后就想到用C++的MFC架构来调用MATLAB编写的计算函数,不就强强联手,各取所长了吗。然后就开始做实验了。我当时想的是MATLAB封装成lib库,然后给MFC调用,网上一搜发现相关的帖子好多,于是开始照做了。

    在实验过程中,遇到很多问题,实在是成功的太痛苦了,成功了以后特意写个帖子记录下。

    环境介绍:

    win10 64位、MatlabR2016a  64位、VS2015 (VS编译的时候可以选32、64位编译。我选的是64 位Release编译)

    一)首先下载安装 MatlabR2016a  64位,并且正确激活.

    我可能下载的是这个吧。https://blog.csdn.net/weixin_42858575/article/details/89309667。差不多应该。

    然后就是如果激活失败了不要慌。根据错误提示,在安装文件夹下,找到生成的lice文件,删掉就可以接着激活了。

    1.安装激活(最好安装在D盘,给C盘留空间)

    2.配置系统路径

    右击此电脑 ->属性 ->高级系统设置->环境变量(系统属性框之高级页)->选中环境变量(S)下的Path ,然后点编辑(不会加的试一试百度)。具体加的几条参考下图。ps: MatlabR2016(安装的运行文件夹)以及它前面的目录信息,根据个人安装情况设置。

    成功激活以后,电脑自己就会配有几条,我也不记得是哪几个,大家参考图片把路径写完整了就行。不要漏,漏了会出现有很多.dll找不到的问题。

    二)建立c++项目。

    不知道为什么参考博主,大都建立的是控制台项目,可能验证阶段好调试吧。我也照着建立了控制台程序。虽然没试,但是肯定 mfc也是可以的。以下例子仅演示建立过程,我实际实验的工程名叫:ConsoleApplication1。大家根据实际放置目录随机应变。

    打开VS2015,在起始页点击 文件(F)->新建(N)->项目(P)弹框:新建项目。

    在 已安装-> 模板 ->Visual C++ -> Win32控制应用程序 ,自己定义好位置名称,点确定,点下一步,点完成。

     ,

    建好的工程如下:

    三)建立Matlab工程

    1)建立功能脚本

    打开Matlab软件,在主页下,点击新建脚本。就会出现一个文件:UntitledX(X是个阿拉伯数字,第一次就是1,依次类推)。下面是命令行窗口。

    在脚本窗口写一个功能函数,实现两数相加,并将结果保存在txt文件中的操作。然后保存文件到刚建立的C++工程中(这样的话,引用那些编译出来的文件路径比较好写)。Ps:保存的时候,系统会自动给你的文件命名和函数名一样,比如我的是libMyAdd.m。我没改过,听说改成不一致也可以。新手别尝试。

    为了方便你们直接复制(因为那两引号有可能整错),这个文件将计算结果先保存在了一个txt中:

    function c =libMyAdd(a,b)
    c = 2*a+b;
    save('D:\data.txt','c','-ascii');
    end

    2)验证功能函数

    写完功能函数之后,可以先验证一下这个函数功能没问题。在命令窗口输入命令:

    首先到脚本的目录下(不这样系统找不到你这个功能函数报错):cd D:\TestProMatlab\protest\mex_test\   

    然后直接调用函数名,看结果是否正确,也看下是否有txt生成,多试几次,会发现 txt有在更新。

    3)验证无误就可以打包了

    打包命令:mcc  -W cpplib:libMyAdd -T link:lib libMyAdd

    命令解释:mcc  -W cpplib<cpplib表示要打包C++动态库>:libMyAdd<libMyAdd是打包出来的lib库名字,可以和.m不一样> -T link:lib libMyAdd<libMyAdd是你写的功能函数XXX.m 的名,但是这里不加那个 .m。我看有人说可以写成 XXX.m -C的方式,我这样试的没成功,不予评价>

    出现如下这样就编译成功了,时间比较久。十来秒。

    >> mcc  -W cpplib:libMyAdd -T link:lib libMyAdd
    使用 'Microsoft Visual C++ 2015 Professional' 编译。 
    >>                                                                                       编译之后会出现这么多文件,有用的就是 .h  .lib  .dll

    四)VS中,调用lib 库

    我之前跟着别人的帖子试过狠多版本,当我成功了以后,就觉得很有可能是VS2015这个坑爹工具导致的不成功,它配置编译环境实在是太不友好了。我建议大家像我一样,1)直接把路径写在程序里,2)配到系统变量里。别信项目->属性配置那一套。一来配置的很多,如果失败了多来几次烦死你。二来移植性不好。三来不好判断配置是否正确,是否生效。对新手很可能目标是要编64位的程序,但是配置都配给了32位的(属实不容易发现)。

    1)在C++文件目录下放置文件夹 include和lib

    vs里面的文件夹嵌套的挺复杂,如果不知道具体位置的话,可以自己添加test.cpp(源文件右键,参考下面添加文件那里最后选“新建项”),最后检查自己加的文件在哪那么执行目录就在哪。

    2)拷贝一下文件到include  和  lib(里面还有个 Exports lib,我不确定是哪一个就都拷贝了) 。

    多出来的那个 MWArray.dll是后面跑程序时,系统提示缺少我加进去的。

     

    3)在程序中,添加相关头文件、资源文件。

    添加头文件:选中头文件右键 -> 添加(D)-> 现有项(G)然后选择放在include下的 libMyAdd.h

    添加资源文件:选中资源文件右键 -> 添加(D)-> 现有项(G)然后选择  libMyAdd.dll(这个文件我拷贝到了整个工程文件夹下,情况如上一行最后一个图,

    程序源代码参考:

    ,

    // ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
    //

    #include "stdafx.h"
    #include <iostream>
    #include <fstream>
    #include "include\libMyAdd.h"

    #pragma comment(lib, ".\\lib\\libMyAdd.lib" )
    #pragma comment(lib, ".\\lib\\mclmcrrt.lib")
    #pragma comment(lib, ".\\lib\\mclmcr.lib")
    #pragma comment(lib, ".\\lib\\libmx.lib")
    #pragma comment(lib, ".\\lib\\libmat.lib")


    using namespace std;

    int main()
    {
        bool isOk = 0;
        printf("beginning.\n");
        if (!libMyAddInitializeWithHandlers(NULL, 0))
        {
            printf( "Could not initialize the application.\n");
            return -1;
        }
        printf("isOk =%d.\n", isOk);
        isOk = libMyAddInitialize();
        printf("isOk =%d.\n", isOk);

        mwArray a(1, 1, mxDOUBLE_CLASS);
        mwArray b(1, 1, mxDOUBLE_CLASS);
        a(1, 1) = 2.0;
        b(1, 1) = 1.2;

        mwArray z(1, 1, mxDOUBLE_CLASS);

        libMyAdd(1, z, a, b);
        cout <<"2*"<< a << "+" << b << "=" << z << endl;
        //printf("a=%f,b=%f,a+b=z =%f.\n",&a(1,1),b,&z(1,1));

        mclWaitForFiguresToDie(NULL);

        libMyAddTerminate();
        mclTerminateApplication();

        return 0;
    }

    4)程序编译运行

    注意位数的设置,如果想看值,必须要用cout,printf看不到。(然后外加的动态库也可以参加 Release的调试,但是得配合跳过)

    运行的时候,可能会报缺少依赖的库,一次性记下来(因为他们都在一个目录下放着,一个个找太麻烦了),然后找到拷贝到准备的文件夹include 、 lib就好。

    ps: 所需的dll文件通常都在“D:\XXX\MatlabR2016a\bin\win64”这个文件夹可以找到

    matlab代码不是还将这个结果保存在 TXT中了吗,以下是对生成文件的查看。

    五)参考

    本人两方都比较小白,这两个软件除了大学课设都没怎么用过,能成功都是靠其他高手帖子的启发。这里详细介绍,予以大家参考

    参考帖子1

    https://blog.csdn.net/weixin_34008805/article/details/86189875

    标题:matlab 与 VC 混编函数参数传递<2>

    推荐理由:这个帖子写的一看好像与没混编没关系,但是,它对与混编后对Matlab的使用很有意义。比如我之前不明白为什么2数相加,出1数,参数接口为什么不是3个,而是4个。它不仅解决了这个问题,还让我对matlab的输出有了更广的应用启发。

    参考帖子2

    https://blog.csdn.net/qq_36165459/article/details/81283932?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control

    标题:C++调用Matlab生成的DLL动态链接库进行混合编程(win10+VS2015+Matlab2016b)

    推荐理由:我最开始就是参考这个帖子操作,可惜怎么也成功不了,很绝望。但是这样帖子的系统和版本和我的很像,给了我很大的信心觉得我肯定可以实验成功。

    后来的实验深入,我发现这里提供的测试程序很好用。我现在还没有试他的图像的处理的那块实验,但是觉得灰常有价值。对我来说是方法行不通,但是理论可以学的好帖子。

    参考帖子3

    https://blog.csdn.net/w_b_h/article/details/74570852

    标题:matlab函数编译成库供C++调用(非常详细)

    推荐理由:这是对我操作最有用的帖子了。可惜就是这个帖子里的例子不好引用,让新手对这个帖子不能照猫画虎。如果他的例子是 求和啥的应该会更多评价。我也是实验好几天对联编有点了解,才对这帖子内容和上个帖子的内容移花接木操作了一番,最终成功的。

    我在他的指导方法下,我一个属性也没有配置就执行成功,感谢这位大大的分享,大家看到我的帖子可以多进去支持支持。

    其他很多帖子也都看过,大家操作内容都差不多,那些负责的配属性变量的我都不成功,也不清楚怎么回事。大家多参考,多尝试,祝你们好运。

     

    其他(我没试,就是看了看。没有推荐理由):

    https://blog.csdn.net/China_Rocky/article/details/104592488

    标题:QT和matlab混合编程实现加法运算

    https://blog.csdn.net/HongAndYi/article/details/79477031

    Qt与Matlab混合编程中mwArray数组使用详解

     

    展开全文
  • 我用mfc、opencv和matlab写的一个程序,在matlab的函数调用时出了一个错误,不知道该如何解决 [img=... 这个错误就是在调用matlab函数之后弹出的 求大神解答
  • VS2012(C++ MFC 环境下)调用MATLAB 2013 自定义函数(.m 文件)
  • 注意:若Matlab代码中需要调用Matlab库函数,则需要在C++调用Matlab代码前加一个初始化函数:MyFunInitialize(),该函数为XXXInitialize()其中XXX与生成的XXX.h、XXX.lib、XXX.dll同名。 (1)编译B.m文件 1)第一...
  • c++调用matlab笔记(MFC

    千次阅读 2017-09-26 16:07:47
    首先,我在C++代码中调用matlab函数主要采用matlab引擎的方式。 C++代码·中的调用matlab部分如下:Engine *ep; ep = engOpen(NULL);//开启matlab引擎 engEvalString(ep, "x=0:0.05:2*pi;y=sin(x);plot(x,y,'.b')")...
  • MFCMATLAB混合编程

    热门讨论 2009-04-01 15:47:33
    本程序详细的实现了如何在VC下面调用Matlab函数进行三维绘图
  • 我在matlab中建立一个函数并编译成dll,然后VS2008中的MFC调用dll,在我的电脑上成功运行,并生成可执行文件,也能成功运行。但是在别的电脑上就出现错误,错误原因是在我的电脑上DLL可以初始化,在别的电脑上初始化...
  • c++调用matlab例子

    2011-05-11 16:56:01
    c++调用matlab例子,在WindowsXP(SP2), MATLAB R2007b, VC6.0下实现。 具体的步骤是: 1). 设置系统环境变量path,path里面要包括MATLAB的exe, dll那个路径 %MATLAB_PATH%\bin\win32 只要MATLAB是正确安装,它应该...
  • 第三个程序: 采用多线程的MFC调用matlab函数: 同样的加入相关文件 #include "stdafx.h" #include "matlabPlotMFC2.h" #include "matlabPlotMFC2Dlg.h" #include "matlab_header.h" #pragma comment(lib, "plot.lib")...
  • 启动程序后,点击调用matlab函数的按钮就无故卡死,在调试模式下点击按钮卡几分钟后弹出下面提醒,网上查询后判断问题为matlab生成的Com组件中代码存在问题 matlab原代码:没有try catch、绝对路径加载图片——不...
  • MFC调用COM接口代码: void Ctest_com2Dlg::OnBnClickedButton1() { CoInitialize(NULL); HRESULT hresult; CLSID clsid; hresult=::CLSIDFromProgID(OLESTR("test.testclass.1_0"), &clsid); if (!(FAILED...
  • matlabMFC

    2013-06-24 11:15:00
    我在设置的过程中,遇到了不少问题,花了多半天的时间,终于解决了,顺利地在vc中调用matlab 生成的dll文件中的函数,并返回一个值,探出对话框,显示正确。这种混合编程的方式不能脱离matlab环境,如果需要发布独立...
  • 有了这个想法后,便在网上搜索相关的资料,实际调用matlab生成库时,没有简单的办法可以使项目编译成功,便采用MFC内部调用matlab函数的方式完成此功能。 首先在电脑上安装matlab软件(我使用的win7 64位系统、VS...
  • MFC调用matlab时,我用两个按钮实现调用matlab计算的,调用的是同一个函数,只是参数不一样而已。问题就来了:第一次调用正确,第二次就不对了。错误是:index out of bounds(索引越界)。 我把m文件的代码贴出来...
  • com和matlab编程

    2012-04-05 20:49:07
    演示了如何利用mfc中的com接口来调用matlab中的函数
  • WPF(C#)与MATLAB混合编程WPF可以为开发者提供便捷地构建用户交互界面的解决方法,而matlab则在科学计算方面有着无与伦比的优势,因此在一些需要将...1、编辑需要被WPF程序调用matlab函数文件,例如:test.m;2、编...
  • VC++与MATLAB混合编程

    千次阅读 2017-06-13 11:37:06
    VC调用matlab函数计算复杂数学表达式具有很好的应用前景,在编写matlab程序时不需要处理变量的类型问题,而且支持矩阵运算及其它复杂运算,浮点运算精度高。VC的MFC框架支持可视化的人机交互界面,因此将VC与MATLAB...
  • WPF(C#)与MATLAB混合编程

    2019-10-01 17:57:22
    WPF(C#)与MATLAB混合编程 WPF可以为开发者提供便捷地构建用户交互界面的解决方法,而matlab则在科学计算方面有着无与伦比的优势,因此在一些需要将科学算法转换为应用软件...1、编辑需要被WPF程序调用matlab函数...
  • MATLAB6.x & VC6.0: 将plot图片显示在...通过调用mcc,可以将MATLAB程序编译为C/C++或库文件,并嵌入到自己的VC应用程序中。该方法不仅适于纯粹的运算代码,也适于图形函数,比如plot等等。不过遇到的问题是,每...

空空如也

空空如也

1 2 3
收藏数 45
精华内容 18
关键字:

mfc调用matlab函数

matlab 订阅