VS2019与matlab 2019a混合编程实例
前言
最近因为项目需要,需要把matlab工程在vs2019中调用,想着先测试一下这个功能怎么用再进行实际工程的调用,然后…,好家伙,花了一周多的时间在弯路上,最后还是通过我的老电脑才解决的问题,希望能对大家有点点帮助。在网上找的教程很多,我尽量都引用源路径,但是有些是真的不记得了,所以希望其他博主不要介意,先说句不好意思了。
windows环境的配置
==右键我的电脑->属性->高级系统设置->高级->环境变量,在系统变量和用户变量都添加
(D:\install detail\matlab2019a\bin\win64)==这个文件夹是根据你自己matlab的安装路径决定的,只要是bin下面的win64就行(32位系统的就是win32)。
这个配置十分重要,如果没有配置这个的话,在后面的程序中会出现类似于:
找不到mclmcr.dll文件,建议重新安装程序啥的,是一个vs的弹窗显示的。
这个是来源于链接: VS与matlab混合编程.
Matlab 2019a环境的配置
Matlab 需要配置你所用的调用软件的代码生成器,基本上根据这一篇来完成就可以了。
VS2016 调用matlab脚本 ——缺少mclmcr.dll.
-
但是需要注意的是,一定要使用mbuild -setup来设置你的编译软件,我中间就是没有使用mbuild -setup,来设置我的编译软件,会导致你调用的时候会出现错误:
无法解析的外部符号"__declspec(dllimport) public: int __thiscall -
这种错误大部分是由于你matlab 配置生成的软件和vs版本不兼容造成的,中间也试过用以前老电脑生成的dll等文件来进行配置,出现的就是这种问题 。
还有会出现错误严重性 代码 说明 项目 文件 行 禁止显示状态
错误 LNK2019 无法解析的外部符号 main,函数 “int __cdecl invoke_main(void)” (?invoke_main@@YAHXZ) 中引用了该符号 -
这种错误是由于没有定义main函数的,中间也会出现过,找了很多方法,但是主要还是由于没有配置好
-
在环境的配置中可能会找不到你所用的编译软件,可以按照如下方法添加即可:
Matlab2016及以上版本设置VS编译器.
Matlab生成库
①matlab函数
function c = MyAdd(a,b)
c = a+b;
这就是一个相加的函数。
②然后记得要看matlab2019设置成这样子
这里是配置好之后,mex -setup 后出现的,直接点击Microsoft Visual C++ 2019 就行了。
还有mbuild -setup
这样后就可以执行:
mcc -W cpplib:libMyAdd -T link:lib MyAdd.m
执行完成后出现:
之后你的文件夹就会出现如下文件:
VS2019调用dll
①创建一个win32工程
②将x86改为x64(matlab生成的库是64位的)
③创建一个空白的c++程序
④将如下代码放进去空白的c++程序里面
#include "iostream"
#include "engine.h"
#include "mclmcr.h"
#include "mclcppclass.h"
#include "libMyAdd.h"
using namespace std;
int _tmain(int argc, const char* argv[])
{
if (!libMyAddInitialize())
{
//initilize failed!!!"<<std::endl;
std::cout << "错误..." << std::endl;
return -1;
}
double a = 6;
double b = 9;
double c;
mwArray mwA(1, 1, mxDOUBLE_CLASS);
mwArray mwB(1, 1, mxDOUBLE_CLASS);
mwArray mwC(1, 1, mxDOUBLE_CLASS);
mwA.SetData(&a, 1);
mwB.SetData(&b, 1);
MyAdd(1, mwC, mwA, mwB);
c = mwC.Get(1, 1);
cout << c << endl;
system("PAUSE");
return 0;
}
⑤将生成的libMyAdd.dll,libMyAdd.lib,libMyAdd.h复制粘贴到你当前vs2019工程的目录下
⑥配置工程的属性:右击项目:
- 属性->VC++目录->包含目录->编辑->添加(D:\install detail\matlab2019a\extern\include)(这是你的matlab安装目录)
- 属性->VC++目录->库目录->编辑->添加(D:\install detail\matlab2019a\extern\lib\win64\microsoft)
- 属性->链接器->输入->附加依赖项->
libeng.lib;libmat.lib;libmex.lib;libmx.lib;mclmcrrt.lib;mclmcr.lib;libMyAdd.lib
听说是不用添加那么多个,但是我没试过,还是规规矩矩地来吧,到这一步基本已经完成了,生成解决方案后运行就行了。最终结果
VS2019 直接调用Matlab引擎
VS2019要运用到Matlab里面的函数的第二种方法,直接调用Matlab,这种方法算是直接调用Matlab来直接处理函数的内容。
①创建win32工程,将x86改为x64
②配置工程的属性:右击项目:
- 属性->VC++目录->包含目录->编辑->添加(D:\install detail\matlab2019a\extern\include)(这是你的matlab安装目录)
- 属性->VC++目录->库目录->编辑->添加(D:\install detail\matlab2019a\extern\lib\win64\microsoft)
- 属性->链接器->输入->附加依赖项->
libeng.lib;libmat.lib;libmex.lib;libmx.lib;mclmcrrt.lib;mclmcr.lib;
或者采用以下方法来添加:
// import necessary lib
#pragma comment( lib, “libeng.lib”)
#pragma comment( lib, “libmx.lib”)
#pragma comment( lib, “libmat.lib”)
③新建一个新c++文件,将以下代码添加进新建的c++程序
// CMatlab.cpp : 定义控制台应用程序的入口点。
//
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "engine.h" // add header file
// import necessary lib
#pragma comment( lib, "libeng.lib")
#pragma comment( lib, "libmx.lib")
#pragma comment( lib, "libmat.lib")
int main(void)
{
Engine* ep;
// open engine
if (!(ep = engOpen(NULL)))
{
fprintf(stderr, "\nCan't start MATLAB engine\n");
return EXIT_FAILURE;
}
// generate variables
int Nsample = 50;
const double PI = 3.1415926;
double* t = new double[Nsample];
for (int i = 0; i < Nsample; i++)
{
t[i] = i * 2 * PI / Nsample;
}
mxArray* T = NULL, * result = NULL;
T = mxCreateDoubleMatrix(1, Nsample, mxREAL);
memcpy((void*)mxGetPr(T), (void*)t, Nsample * sizeof(t[0]));
engPutVariable(ep, "T", T); // put data to engine
// execute matlab operations
engEvalString(ep, "Y=sin(T);");
engEvalString(ep, "plot(T,Y);");
engEvalString(ep, "title('y=sin(t)');");
engEvalString(ep, "xlabel('t');");
engEvalString(ep, "ylabel('y');");
printf("Hit return to continue\n");
fgetc(stdin);
// clean operation(don't forget!!!)
mxDestroyArray(T);
engEvalString(ep, "close;");
// close engine
engClose(ep);
return EXIT_SUCCESS;
}
④运行结果
注意:如果引擎打开失败,可以试试手动打开Matlab的引擎
①管理员模式打开命令行
(win10 下的方法:Win10怎么以管理员身份运行CMD命令提示符.)
②打开你安装的Matlab的安装目录下的bin文件夹:
D:
cd D:\install detail\matlab2019a\bin
③输入:matlab \regeserver
就会打开一个matlab的界面了,这样子就免启动了
但是,还有可能会发现其他错误,例如:找不到xxx.dll文件,那么,你就要在vs2019工程里面将可执行目录添加进去,也就是进行以下两步:
①右击工程打开属性页->配置属性->调试->环境->添加
PATH = D:\install detail\matlab2019a\bin\win64(是你的安装目录)
②配置属性->VC++目录->常规->可执行目录->添加
PATH = D:\install detail\matlab2019a\bin\win64(是你的安装目录)
原文连接:
VS2017调用Matlab2016b进行绘图.
VS通过调用matlab引擎方式在VS里调用matlab函数和自己写的.m文件.
总结
其实VS调用Matlab生成的dll文件已经是比较成熟的事情了,其实环境搭配并没有那么的困难,只是第一次接触这个东西,走的弯路有点多,还有一个就是我电脑上装着两个版本的Matlab的,一个是2016吧,一个是2019a,之前在我的旧电脑上运行成功后,以为是两个Matlab有冲突,然后我把两个都卸载了,只装了一个,但是后来发现了问题后,并不是,这个对Matlab版本冲突没有关系,只要是生成的dll文件方法是路径是正确的,那么问题都不大,可能是网上的人遇到的问题都不一样,真的有一些问题能让你直接崩溃,根本找不到其他人遇到过的,或者是启动文件的关系的,所以要注意,有提示总比没提示好,中间还试过出现好几次无解的错误,说什么无效运行,都是由于matlab配置不对造成的,希望我这篇文章能够为大家带来一点帮助。
列举一些我参考过的博主的文章
C++ MATLAB 混合编程——VS项目调用MATLAB函数.
MATLAB与C++混合编程:动态链接库方法实现混合编程及常见错误解决办法.
在matlab2019a装MatConvNet中遇到的问题及解决.
Matlab Compiler SDK 使用步骤及常见问题总结(全).