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

阅读: 评论:0

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

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软件安装目录)

…MATLABexternlibwin32microsoft;
…MATLABbinwin32
Computer - > Properties -> Advanced system settings -> Environment Variables -> System Variables -> path, 添加
…MATLABruntimewin32;
…MATLABbin;
…MATLABbinwin32
…MATLABexternlibwin32microsoft;

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!"));       }// 为变量分配内存空间,可以查帮助mwArraymwArray 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 liblibAddTerminate();// 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_DATALearning_OpenCVVS_learning_opencvTestMatlab副本 : fatal error LNK1120: 12 个无法解析的外部命令
 **解决方案:1.VS2013的编译平台换成X642.安装32位MATLAB2014a**

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

本文发布于:2024-02-04 22:23:39,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170717766960196.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:函数   MATLAB   MFC
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23