MATLAB与C++/MFC混合编程;调用MATLAB函数
2017-08-12 22:26
1011 查看
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 c63a } 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
相关文章推荐
- C++和Matlab混合编程——MATLAB调用c++函数(以svmlight为例)
- c/c++/MFC 调用 js 函数代码
- matlab函数编译成库供C++调用(非常详细)
- c++调用matlab函数——配置
- C/C++下调用matlab函数操作说明
- c++程序里如何调用MATLAB中的函数
- matlab和C/C++混合编程--调用opencv
- matlab和C/C++混合编程--调用opencv
- Visual Studio 2010中的C++程序调用matlab程序代码 混合编程
- MEX文件调试—MATLAB调用C++程序—混合编程
- C#与DLL和COM的混合编程(1)-C#调用C++写的非托管的DLL中导出的函数
- c++与matla混合编程之一---调用matlab工具箱内的函数
- c++调用matlab笔记(MFC)
- C#调用C++动态链接库之Win32dll(函数)、MFCdll(对话框)
- C/C++混合编程,实现C/C++间的函数相互调用详解
- Linux下c++调用自己编写的matlab函数:通过mcc动态链接库.so实现
- 小字典之MFC简单的多线程调用类的成员函数实现逐步画线功能 VS2015 C++ 完成
- Linux下c++调用自己编写的matlab函数:通过mcc动态链接库.so实现
- [matlab]--调用不同路径下函数的方法(类似c++#include(xxx))
- C++和Matlab混合编程——VS调用Matlab函数